Skip to content

Commit

Permalink
feat: forenklet envConfig for Kafka secrets
Browse files Browse the repository at this point in the history
  • Loading branch information
Kyrremann committed Mar 1, 2022
1 parent ea0a7d6 commit 576c1e4
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 140 deletions.
8 changes: 7 additions & 1 deletion pkg/aiven/aiven.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,21 @@ const (
Kafka Service = iota
)

var Services = []string{"kafka"}

func ServiceFromString(service string) (Service, error) {
switch strings.ToLower(service) {
case "kafka":
case Services[0]:
return Kafka, nil
default:
return -1, fmt.Errorf("unknown service: %v", service)
}
}

func (p Service) String() string {
return Services[p]
}

type KafkaProperties struct {
Pool KafkaPool
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/config/java.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ type Java struct {

func (k *Java) WriteConfigToFile() error {
if err := k.write(); err != nil {
return fmt.Errorf("could not write %s to file: %s", KafkaSchemaRegistryEnvName, err)
return fmt.Errorf("could not write %s to file: %s", JavaConfigName, err)
}
return nil
}
Expand Down
102 changes: 30 additions & 72 deletions pkg/config/kafka_environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,105 +2,63 @@ package config

import (
"fmt"
"github.com/nais/cli/pkg/aiven"
"github.com/nais/cli/pkg/common"
"github.com/nais/cli/pkg/consts"
v1 "k8s.io/api/core/v1"
"path/filepath"
"strings"
"time"
)

const (
KafkaSchemaRegistryEnvName = "kafka-secret.env"
)

func NewEnvConfig(secret *v1.Secret, dest string, service aiven.Service) (Config, error) {
switch service {
case aiven.Kafka:
return &KafkaEnvironment{
Envs: fmt.Sprintf("# nais-cli %s .env\n", time.Now().Truncate(time.Minute)),
Secret: secret,
PrefixPath: dest,
RequiredFiles: map[string]RequiredFile{
consts.KafkaCertificateKey: {consts.KafkaCertificateCrtFile, consts.KafkaCertificatePathKey, true},
consts.KafkaPrivateKeyKey: {consts.KafkaPrivateKeyPemFile, consts.KafkaPrivateKeyPathKey, true},
consts.KafkaCAKey: {consts.KafkaCACrtFile, consts.KafkaCAPathKey, true},
consts.KafkaClientKeyStoreP12File: {consts.KafkaClientKeyStoreP12File, consts.KafkaKeystorePathKey, false},
consts.KafkaClientTruststoreJksFile: {consts.KafkaClientTruststoreJksFile, consts.KafkaTruststorePathKey, false},
},
}, nil
default:
return nil, fmt.Errorf("unknown service: %v", service)
}
}

type KafkaEnvironment struct {
Envs string
Secret *v1.Secret
PrefixPath string
RequiredFiles map[string]RequiredFile
type FileTuple struct {
Filename string
PathKey string
}

func (k *KafkaEnvironment) WriteConfigToFile() error {
if err := k.write(); err != nil {
return fmt.Errorf("could not write %s to file: %s", KafkaSchemaRegistryEnvName, err)
func getSecretsToSaveToFile() []FileTuple {
return []FileTuple{
{consts.KafkaCertificateCrtFile, consts.KafkaCertificatePathKey},
{consts.KafkaPrivateKeyPemFile, consts.KafkaPrivateKeyPathKey},
{consts.KafkaCACrtFile, consts.KafkaCAPathKey},
{consts.KafkaClientKeyStoreP12File, consts.KafkaKeystorePathKey},
{consts.KafkaClientTruststoreJksFile, consts.KafkaTruststorePathKey},
}
return nil
}

func (k *KafkaEnvironment) write() error {
if err := common.WriteToFile(k.PrefixPath, KafkaSchemaRegistryEnvName, []byte(k.Envs)); err != nil {
return fmt.Errorf("write envs to file: %s", err)
func getEnvsToSaveToFile() []string {
return []string{
consts.KafkaBrokersKey, consts.KafkaCredStorePasswordKey, consts.KafkaSchemaRegistryKey,
consts.KafkaSchemaRegistryPasswordKey, consts.KafkaSchemaRegistryUserKey, consts.KafkaCertificatePathKey,
consts.KafkaPrivateKeyPathKey, consts.KafkaCAPathKey,
}
return nil
}

func (k *KafkaEnvironment) Set(key string, value []byte) {
k.Envs += fmt.Sprintf("%s=\"%s\"\n", key, string(value))
func WriteKafkaEnvConfigToFile(secret *v1.Secret, destinationPath string) error {
return writeConfigToFile(secret, destinationPath, KafkaSchemaRegistryEnvName, getEnvsToSaveToFile(), getSecretsToSaveToFile())
}

func (k *KafkaEnvironment) SetPath(key, path string) {
k.Envs += fmt.Sprintf("%s=%s\n", key, path)
}
func writeConfigToFile(secret *v1.Secret, destinationPath, destinationFilename string, envsToSave []string, secretFilesToSave []FileTuple) error {
envsToFile := fmt.Sprintf("# nais-cli %s .env\n", time.Now().Truncate(time.Minute))
for _, secretToFile := range secretFilesToSave {
err := common.WriteToFile(destinationPath, secretToFile.Filename, secret.Data[secretToFile.PathKey])
if err != nil {
return err
}

func (k *KafkaEnvironment) Generate() (string, error) {
err := requiredSecretDataExists(k.RequiredFiles, k.Secret.Data, KafkaSchemaRegistryEnvName)
if err != nil {
return "", err
envsToFile += fmt.Sprintf("%s=\"%s\"\n", secretToFile.PathKey, filepath.Join(destinationPath, secretToFile.Filename))
}

for key, value := range k.Secret.Data {
if err := k.toFile(key, value); err != nil {
return "", fmt.Errorf("write to file for key: %s\n %s", key, err)
}
k.toEnv(key, value)
for _, key := range envsToSave {
envsToFile += fmt.Sprintf("%s=\"%s\"\n", key, string(secret.Data[key]))
}
return k.Envs, nil
}

func (k *KafkaEnvironment) toEnv(key string, value []byte) {
if key == consts.KafkaBrokersKey {
k.Set(key, value)
}
if key == consts.KafkaCredStorePasswordKey {
k.Set(key, value)
}
if strings.HasPrefix(key, consts.KafkaSchemaRegistryKey) {
k.Set(key, value)
err := common.WriteToFile(destinationPath, destinationFilename, []byte(envsToFile))
if err != nil {
return err
}
}

func (k *KafkaEnvironment) toFile(key string, value []byte) error {
path := k.PrefixPath
if requiredFile, ok := k.RequiredFiles[key]; ok {
if err := common.WriteToFile(path, requiredFile.Filename, value); err != nil {
return err
}
k.SetPath(requiredFile.PathKey, filepath.Join(path, requiredFile.Filename))
if requiredFile.IncludeInEnv {
k.Set(key, value)
}
}
return nil
}
42 changes: 11 additions & 31 deletions pkg/config/kafka_environment_test.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
package config

import (
"github.com/nais/cli/pkg/aiven"
"github.com/nais/cli/pkg/consts"
"github.com/nais/cli/pkg/test"
"github.com/stretchr/testify/assert"
"io/ioutil"
"os"
"path/filepath"
"strings"
"testing"
)

func TestKafkaEnvironmentConfigGenerated(t *testing.T) {

var envKeys = []string{
consts.KafkaCAKey,
consts.KafkaCertificateKey,
Expand All @@ -23,39 +23,19 @@ func TestKafkaEnvironmentConfigGenerated(t *testing.T) {
}

tmpDest := test.SetupDest(t)
kcatConfig, err := NewEnvConfig(test.SetupSecret(envKeys), tmpDest, aiven.Kafka)
err := WriteKafkaEnvConfigToFile(test.SetupSecret(envKeys), tmpDest)
assert.NoError(t, err)

result, err := kcatConfig.Generate()
result, err := ioutil.ReadFile(filepath.Join(tmpDest, KafkaSchemaRegistryEnvName))
assert.NoError(t, err)

assert.True(t, strings.Contains(result, consts.KafkaClientTruststoreJksFile))
assert.True(t, strings.Contains(result, consts.KafkaCredStorePasswordKey))
assert.True(t, strings.Contains(result, consts.KafkaSchemaRegistryKey))
assert.True(t, strings.Contains(result, consts.KafkaCertificateKey))
assert.True(t, strings.Contains(result, consts.KafkaCAKey))
assert.True(t, strings.Contains(result, consts.KafkaPrivateKeyKey))
assert.True(t, strings.Contains(result, consts.KafkaClientKeyStoreP12File))

defer os.Remove(tmpDest)
}

func TestKafkaEnvironmentSecrettMissingRequiredData(t *testing.T) {

var envKeys = []string{
consts.KafkaCAKey,
consts.KafkaCertificateKey,
consts.KafkaPrivateKeyKey,
consts.KafkaClientKeyStoreP12File,
consts.KafkaCredStorePasswordKey,
consts.KafkaSchemaRegistryKey,
}

tmpDest := test.SetupDest(t)
kcatConfig, err := NewEnvConfig(test.SetupSecret(envKeys), tmpDest, aiven.Kafka)
assert.NoError(t, err)
_, err = kcatConfig.Generate()
assert.EqualError(t, err, "can not generate kafka-secret.env config, secret missing required key: client.truststore.jks")
assert.True(t, strings.Contains(string(result), consts.KafkaClientTruststoreJksFile))
assert.True(t, strings.Contains(string(result), consts.KafkaCredStorePasswordKey))
assert.True(t, strings.Contains(string(result), consts.KafkaSchemaRegistryKey))
assert.True(t, strings.Contains(string(result), consts.KafkaCertificateKey))
assert.True(t, strings.Contains(string(result), consts.KafkaCAKey))
assert.True(t, strings.Contains(string(result), consts.KafkaPrivateKeyKey))
assert.True(t, strings.Contains(string(result), consts.KafkaClientKeyStoreP12File))

defer os.Remove(tmpDest)
}
24 changes: 13 additions & 11 deletions pkg/consts/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,17 @@ const (
KafkaClientKeyStoreP12File = "client.keystore.p12"
KafkaClientTruststoreJksFile = "client.truststore.jks"

KafkaCertificatePathKey = "KAFKA_CERTIFICATE_PATH"
KafkaPrivateKeyPathKey = "KAFKA_PRIVATE_KEY_PATH"
KafkaCAPathKey = "KAFKA_CA_PATH"
KafkaKeystorePathKey = "KAFKA_KEYSTORE_PATH"
KafkaTruststorePathKey = "KAFKA_TRUSTSTORE_PATH"
KafkaCertificateKey = "KAFKA_CERTIFICATE"
KafkaPrivateKeyKey = "KAFKA_PRIVATE_KEY"
KafkaCAKey = "KAFKA_CA"
KafkaBrokersKey = "KAFKA_BROKERS"
KafkaSchemaRegistryKey = "KAFKA_SCHEMA_REGISTRY"
KafkaCredStorePasswordKey = "KAFKA_CREDSTORE_PASSWORD"
KafkaCertificatePathKey = "KAFKA_CERTIFICATE_PATH"
KafkaPrivateKeyPathKey = "KAFKA_PRIVATE_KEY_PATH"
KafkaCAPathKey = "KAFKA_CA_PATH"
KafkaKeystorePathKey = "KAFKA_KEYSTORE_PATH"
KafkaTruststorePathKey = "KAFKA_TRUSTSTORE_PATH"
KafkaCertificateKey = "KAFKA_CERTIFICATE"
KafkaPrivateKeyKey = "KAFKA_PRIVATE_KEY"
KafkaCAKey = "KAFKA_CA"
KafkaBrokersKey = "KAFKA_BROKERS"
KafkaSchemaRegistryKey = "KAFKA_SCHEMA_REGISTRY"
KafkaSchemaRegistryPasswordKey = "KAFKA_SCHEMA_REGISTRY_PASSWORD"
KafkaSchemaRegistryUserKey = "KAFKA_SCHEMA_REGISTRY_USER"
KafkaCredStorePasswordKey = "KAFKA_CREDSTORE_PASSWORD"
)
32 changes: 8 additions & 24 deletions pkg/secret/secret.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ const (

type Secret struct {
Secret *v1.Secret
ConfigType string
DestinationPath string
Service aiven.Service
}
Expand Down Expand Up @@ -87,26 +86,27 @@ func hasAnnotation(secret *v1.Secret, key string) bool {
return false
}

func (s *Secret) CreateAllConfigs() error {
func (s *Secret) CreateKafkaConfigs() error {
if err := s.CreateJavaConfig(); err != nil {
return err
}
if err := s.CreateKCatConfig(); err != nil {
return err
}
if err := s.CreateEnvConfig(); err != nil {
err := config.WriteKafkaEnvConfigToFile(s.Secret, s.DestinationPath)
if err != nil {
return err
}
return nil
}

func (s *Secret) Config() error {
log.Default().Printf("generating '%s' from secret '%s'", s.ConfigType, s.Secret.Name)
log.Default().Printf("generating %v config from secret %v", s.Service, s.Secret.Name)
switch s.Service {
case aiven.Kafka:
err := s.CreateAllConfigs()
err := s.CreateKafkaConfigs()
if err != nil {
return fmt.Errorf("generate %s config-type", s.ConfigType)
return err
}
default:
return fmt.Errorf("unkown service: %v", s.Service)
Expand All @@ -118,7 +118,7 @@ func (s *Secret) CreateJavaConfig() error {
javaConfig := config.NewJavaConfig(s.Secret, s.DestinationPath)
_, err := javaConfig.Generate()
if err != nil {
return fmt.Errorf("generate %s config-type", s.ConfigType)
return err
}

if err := javaConfig.WriteConfigToFile(); err != nil {
Expand All @@ -130,27 +130,11 @@ func (s *Secret) CreateJavaConfig() error {
func (s *Secret) CreateKCatConfig() error {
kCatConfig := config.NewKCatConfig(s.Secret, s.DestinationPath)
_, err := kCatConfig.Generate()
if err != nil {
return fmt.Errorf("generate %s config-type", s.ConfigType)
}

if err := kCatConfig.WriteConfigToFile(); err != nil {
return err
}
return nil
}

func (s *Secret) CreateEnvConfig() error {
kafkaEnv, err := config.NewEnvConfig(s.Secret, s.DestinationPath, s.Service)
if err != nil {
return err
}
_, err = kafkaEnv.Generate()
if err != nil {
return fmt.Errorf("generate %s config-type", s.ConfigType)
}

if err := kafkaEnv.WriteConfigToFile(); err != nil {
if err := kCatConfig.WriteConfigToFile(); err != nil {
return err
}
return nil
Expand Down

0 comments on commit 576c1e4

Please sign in to comment.