From f75b25b50dc7ba703f362a44c6e65ec45a82d231 Mon Sep 17 00:00:00 2001 From: Elad Leev Date: Mon, 26 Aug 2024 18:55:04 +0100 Subject: [PATCH] fix missing context, add timeout --- cmd/kubeseal-convert/azurekeyvault.go | 2 +- cmd/kubeseal-convert/azurekeyvault_test.go | 2 +- cmd/kubeseal-convert/gcpsecretsmanager.go | 2 +- cmd/kubeseal-convert/root.go | 2 + cmd/kubeseal-convert/secretsmanager.go | 2 +- cmd/kubeseal-convert/secretsmanager_test.go | 2 +- cmd/kubeseal-convert/vault.go | 4 +- cmd/kubeseal-convert/vault_test.go | 2 +- mocks/AzureKeyVault.go | 10 ++--- mocks/GcpSecretsManager.go | 10 ++--- mocks/SecretsManager.go | 10 ++--- mocks/Vault.go | 10 ++--- .../handlers/azurekeyvault/azurekeyvault.go | 45 ++++++++++++------- .../gcpsecretsmanager/gcpsecretsmanager.go | 21 ++++++--- .../gcpsecretsmanager_test.go | 2 +- .../handlers/secretsmanager/secretsmanager.go | 42 +++++++++-------- .../secretsmanager/secretsmanager_test.go | 3 +- pkg/kubeseal-convert/handlers/vault/vault.go | 35 ++++++++++----- .../handlers/vault/vault_test.go | 2 +- .../interfaces/azurekeyvault.go | 2 +- .../interfaces/gcpsecretsmanager.go | 2 +- .../interfaces/secretmanager.go | 2 +- pkg/kubeseal-convert/interfaces/vault.go | 2 +- 23 files changed, 131 insertions(+), 85 deletions(-) diff --git a/cmd/kubeseal-convert/azurekeyvault.go b/cmd/kubeseal-convert/azurekeyvault.go index 21e5b0e..f68f13d 100644 --- a/cmd/kubeseal-convert/azurekeyvault.go +++ b/cmd/kubeseal-convert/azurekeyvault.go @@ -15,7 +15,7 @@ var azureKeyVaultCmd = &cobra.Command{ PreRun: toggleDebug, Run: func(cmd *cobra.Command, args []string) { secretVal := domain.SecretValues{ - Data: AzureKeyVault.GetSecrets(args[0]), + Data: AzureKeyVault.GetSecrets(args[0], timeout), Name: ParseStringFlag(cmd, "name"), Namespace: ParseStringFlag(cmd, "namespace"), Labels: ParseLabels(cmd), diff --git a/cmd/kubeseal-convert/azurekeyvault_test.go b/cmd/kubeseal-convert/azurekeyvault_test.go index a75affa..664f42d 100644 --- a/cmd/kubeseal-convert/azurekeyvault_test.go +++ b/cmd/kubeseal-convert/azurekeyvault_test.go @@ -19,7 +19,7 @@ func TestAzureKeyVaultCmd(t *testing.T) { // mock azurekeyvault mockAzureKeyVault := mocks.NewAzureKeyVault(t) - mockAzureKeyVault.On("GetSecrets", mock.Anything).Return(map[string]interface{}{ + mockAzureKeyVault.On("GetSecrets", mock.Anything, mock.AnythingOfType("int")).Return(map[string]interface{}{ "key": "value", }, nil) AzureKeyVault = mockAzureKeyVault diff --git a/cmd/kubeseal-convert/gcpsecretsmanager.go b/cmd/kubeseal-convert/gcpsecretsmanager.go index c8608e6..0070abc 100644 --- a/cmd/kubeseal-convert/gcpsecretsmanager.go +++ b/cmd/kubeseal-convert/gcpsecretsmanager.go @@ -15,7 +15,7 @@ var gcpSecretsmanagerCmd = &cobra.Command{ PreRun: toggleDebug, Run: func(cmd *cobra.Command, args []string) { secretVal := domain.SecretValues{ - Data: GcpSecretsManager.GetSecret(args[0]), + Data: GcpSecretsManager.GetSecret(args[0], timeout), Name: ParseStringFlag(cmd, "name"), Namespace: ParseStringFlag(cmd, "namespace"), Labels: ParseLabels(cmd), diff --git a/cmd/kubeseal-convert/root.go b/cmd/kubeseal-convert/root.go index 9973ef3..26a8622 100644 --- a/cmd/kubeseal-convert/root.go +++ b/cmd/kubeseal-convert/root.go @@ -17,6 +17,7 @@ var ( secretName string secretNamespace string rawMode bool + timeout int version = "3.2.0" rootCmd = &cobra.Command{ @@ -54,4 +55,5 @@ func init() { rootCmd.PersistentFlags().StringToStringP("labels", "l", map[string]string{}, "Set k8s labels") rootCmd.PersistentFlags().BoolVar(&rawMode, "raw", false, "[optional] use raw mode") rootCmd.PersistentFlags().BoolVarP(&debug, "debug", "d", false, "[optional] debug logging") + rootCmd.PersistentFlags().IntVarP(&timeout, "timeout", "t", 30, "[optional] get secret timeout") } diff --git a/cmd/kubeseal-convert/secretsmanager.go b/cmd/kubeseal-convert/secretsmanager.go index 5e05531..48ff8be 100644 --- a/cmd/kubeseal-convert/secretsmanager.go +++ b/cmd/kubeseal-convert/secretsmanager.go @@ -15,7 +15,7 @@ var secretsmanagerCmd = &cobra.Command{ PreRun: toggleDebug, Run: func(cmd *cobra.Command, args []string) { secretVal := domain.SecretValues{ - Data: SecretsManager.GetSecret(args[0]), + Data: SecretsManager.GetSecret(args[0], timeout), Name: ParseStringFlag(cmd, "name"), Namespace: ParseStringFlag(cmd, "namespace"), Labels: ParseLabels(cmd), diff --git a/cmd/kubeseal-convert/secretsmanager_test.go b/cmd/kubeseal-convert/secretsmanager_test.go index 1bccc46..59cf3e7 100644 --- a/cmd/kubeseal-convert/secretsmanager_test.go +++ b/cmd/kubeseal-convert/secretsmanager_test.go @@ -20,7 +20,7 @@ func TestSecretManagerCmd(t *testing.T) { // mock secretsmanager mockSecretsManager := mocks.NewSecretsManager(t) - mockSecretsManager.On("GetSecret", mock.Anything).Return(map[string]interface{}{"key": "value"}, nil) + mockSecretsManager.On("GetSecret", mock.Anything, mock.AnythingOfType("int")).Return(map[string]interface{}{"key": "value"}, nil) SecretsManager = mockSecretsManager // test sm command diff --git a/cmd/kubeseal-convert/vault.go b/cmd/kubeseal-convert/vault.go index c49be8d..2f2611b 100644 --- a/cmd/kubeseal-convert/vault.go +++ b/cmd/kubeseal-convert/vault.go @@ -15,14 +15,14 @@ var vaultCmd = &cobra.Command{ PreRun: toggleDebug, Run: func(cmd *cobra.Command, args []string) { secretVal := domain.SecretValues{ - Data: Vault.GetSecret(args[0]), + Data: Vault.GetSecret(args[0], timeout), Name: ParseStringFlag(cmd, "name"), Namespace: ParseStringFlag(cmd, "namespace"), Labels: ParseLabels(cmd), Annotations: ParseAnnotations(cmd), } log.Debugf("secret values: %v", secretVal) - KubeSeal.BuildSecretFile(secretVal, false) + KubeSeal.BuildSecretFile(secretVal, rawMode) }, } diff --git a/cmd/kubeseal-convert/vault_test.go b/cmd/kubeseal-convert/vault_test.go index 37ac7d5..63a9c0c 100644 --- a/cmd/kubeseal-convert/vault_test.go +++ b/cmd/kubeseal-convert/vault_test.go @@ -19,7 +19,7 @@ func TestVaultCmd(t *testing.T) { // mock vault mockVault := mocks.NewVault(t) - mockVault.On("GetSecret", mock.Anything).Return(map[string]interface{}{ + mockVault.On("GetSecret", mock.Anything, mock.AnythingOfType("int")).Return(map[string]interface{}{ "key": "value", }, nil) Vault = mockVault diff --git a/mocks/AzureKeyVault.go b/mocks/AzureKeyVault.go index 55f6885..f95bfd3 100644 --- a/mocks/AzureKeyVault.go +++ b/mocks/AzureKeyVault.go @@ -9,17 +9,17 @@ type AzureKeyVault struct { mock.Mock } -// GetSecrets provides a mock function with given fields: vaultName -func (_m *AzureKeyVault) GetSecrets(vaultName string) map[string]interface{} { - ret := _m.Called(vaultName) +// GetSecrets provides a mock function with given fields: vaultName, timeout +func (_m *AzureKeyVault) GetSecrets(vaultName string, timeout int) map[string]interface{} { + ret := _m.Called(vaultName, timeout) if len(ret) == 0 { panic("no return value specified for GetSecrets") } var r0 map[string]interface{} - if rf, ok := ret.Get(0).(func(string) map[string]interface{}); ok { - r0 = rf(vaultName) + if rf, ok := ret.Get(0).(func(string, int) map[string]interface{}); ok { + r0 = rf(vaultName, timeout) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(map[string]interface{}) diff --git a/mocks/GcpSecretsManager.go b/mocks/GcpSecretsManager.go index 88b32cd..c4087f8 100644 --- a/mocks/GcpSecretsManager.go +++ b/mocks/GcpSecretsManager.go @@ -9,17 +9,17 @@ type GcpSecretsManager struct { mock.Mock } -// GetSecret provides a mock function with given fields: secretName -func (_m *GcpSecretsManager) GetSecret(secretName string) map[string]interface{} { - ret := _m.Called(secretName) +// GetSecret provides a mock function with given fields: secretName, timeout +func (_m *GcpSecretsManager) GetSecret(secretName string, timeout int) map[string]interface{} { + ret := _m.Called(secretName, timeout) if len(ret) == 0 { panic("no return value specified for GetSecret") } var r0 map[string]interface{} - if rf, ok := ret.Get(0).(func(string) map[string]interface{}); ok { - r0 = rf(secretName) + if rf, ok := ret.Get(0).(func(string, int) map[string]interface{}); ok { + r0 = rf(secretName, timeout) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(map[string]interface{}) diff --git a/mocks/SecretsManager.go b/mocks/SecretsManager.go index 0dccaa3..198ebf8 100644 --- a/mocks/SecretsManager.go +++ b/mocks/SecretsManager.go @@ -9,17 +9,17 @@ type SecretsManager struct { mock.Mock } -// GetSecret provides a mock function with given fields: secretName -func (_m *SecretsManager) GetSecret(secretName string) map[string]interface{} { - ret := _m.Called(secretName) +// GetSecret provides a mock function with given fields: secretName, timeout +func (_m *SecretsManager) GetSecret(secretName string, timeout int) map[string]interface{} { + ret := _m.Called(secretName, timeout) if len(ret) == 0 { panic("no return value specified for GetSecret") } var r0 map[string]interface{} - if rf, ok := ret.Get(0).(func(string) map[string]interface{}); ok { - r0 = rf(secretName) + if rf, ok := ret.Get(0).(func(string, int) map[string]interface{}); ok { + r0 = rf(secretName, timeout) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(map[string]interface{}) diff --git a/mocks/Vault.go b/mocks/Vault.go index 79de0d1..12b4dac 100644 --- a/mocks/Vault.go +++ b/mocks/Vault.go @@ -9,17 +9,17 @@ type Vault struct { mock.Mock } -// GetSecret provides a mock function with given fields: secretName -func (_m *Vault) GetSecret(secretName string) map[string]interface{} { - ret := _m.Called(secretName) +// GetSecret provides a mock function with given fields: secretName, timeout +func (_m *Vault) GetSecret(secretName string, timeout int) map[string]interface{} { + ret := _m.Called(secretName, timeout) if len(ret) == 0 { panic("no return value specified for GetSecret") } var r0 map[string]interface{} - if rf, ok := ret.Get(0).(func(string) map[string]interface{}); ok { - r0 = rf(secretName) + if rf, ok := ret.Get(0).(func(string, int) map[string]interface{}); ok { + r0 = rf(secretName, timeout) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(map[string]interface{}) diff --git a/pkg/kubeseal-convert/handlers/azurekeyvault/azurekeyvault.go b/pkg/kubeseal-convert/handlers/azurekeyvault/azurekeyvault.go index 6812b81..c0058f1 100644 --- a/pkg/kubeseal-convert/handlers/azurekeyvault/azurekeyvault.go +++ b/pkg/kubeseal-convert/handlers/azurekeyvault/azurekeyvault.go @@ -3,6 +3,7 @@ package azurekeyvault import ( "context" "fmt" + "time" log "github.com/sirupsen/logrus" @@ -12,47 +13,49 @@ import ( "github.com/eladleev/kubeseal-convert/pkg/kubeseal-convert/interfaces" ) -func createClient(vaultName string) *secrets.Client { - // see https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity#readme-defaultazurecredential: this allows getting credentials - // via either environment variables, managed identity, or 'az login' +func createClient(vaultName string) (*secrets.Client, error) { + /* + see https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity#readme-defaultazurecredential: this allows getting credentials + via either environment variables, managed identity, or 'az login' + */ cred, err := identity.NewDefaultAzureCredential(nil) log.Debugf("Azure identity: %v", cred) if err != nil { - log.Fatalf("Failed to obtain a credential needed to login to the azure vault: %v", err) + return nil, fmt.Errorf("failed to obtain a credential needed to login to the azure vault: %v", err) } vaultURI := fmt.Sprintf("https://%s.vault.azure.net", vaultName) log.Debugf("vaultURI: %v", vaultURI) client, err := secrets.NewClient(vaultURI, cred, nil) if err != nil { - log.Fatalf("Failed to connect to vault '%s': %v", vaultURI, err) + return nil, fmt.Errorf("failed to connect to vault '%s': %v", vaultURI, err) } - return client + return client, nil } // retrieve secret by name with the client -func getSecrets(client *secrets.Client, vaultName string) map[string]interface{} { +func getSecrets(ctx context.Context, client *secrets.Client, vaultName string) (map[string]interface{}, error) { mp := make(map[string]interface{}) pager := client.NewListSecretsPager(&secrets.ListSecretsOptions{}) for pager.More() { log.Debugf("pager: %v", pager) - page, err := pager.NextPage(context.TODO()) + page, err := pager.NextPage(ctx) if err != nil { - log.Fatalf("Failed to retrieve secrets from vault '%s': %v", vaultName, err) + return nil, fmt.Errorf("failed to retrieve secrets from vault '%s': %v", vaultName, err) } for _, secret := range page.Value { - value, err := client.GetSecret(context.TODO(), secret.ID.Name(), secret.ID.Version(), &secrets.GetSecretOptions{}) + value, err := client.GetSecret(ctx, secret.ID.Name(), secret.ID.Version(), &secrets.GetSecretOptions{}) log.Debugf("secret value: %v", value) if err != nil { - log.Fatalf("Failed to retrieve secret '%s' from vault '%s': %v", secret.ID.Name(), vaultName, err) + return nil, fmt.Errorf("failed to retrieve secret '%s' from vault '%s': %v", secret.ID.Name(), vaultName, err) } mp[secret.ID.Name()] = *value.Value } } - return mp + return mp, nil } type AzureKeyVaultImp struct { @@ -62,8 +65,20 @@ func New() interfaces.AzureKeyVault { return &AzureKeyVaultImp{} } -func (*AzureKeyVaultImp) GetSecrets(vaultName string) map[string]interface{} { +func (*AzureKeyVaultImp) GetSecrets(vaultName string, timeout int) map[string]interface{} { log.Debugf("Getting secrets from vault %v", vaultName) - cli := createClient(vaultName) - return getSecrets(cli, vaultName) + // Create a context with a timeout + ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeout)*time.Second) + defer cancel() + + cli, err := createClient(vaultName) + if err != nil { + log.Fatalf("failed to create client: %v", err) + } + + secret, err := getSecrets(ctx, cli, vaultName) + if err != nil { + log.Fatalf("failed to get secret: %v", err) + } + return secret } diff --git a/pkg/kubeseal-convert/handlers/gcpsecretsmanager/gcpsecretsmanager.go b/pkg/kubeseal-convert/handlers/gcpsecretsmanager/gcpsecretsmanager.go index 01ca415..532c0ab 100644 --- a/pkg/kubeseal-convert/handlers/gcpsecretsmanager/gcpsecretsmanager.go +++ b/pkg/kubeseal-convert/handlers/gcpsecretsmanager/gcpsecretsmanager.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "strings" + "time" log "github.com/sirupsen/logrus" @@ -37,14 +38,13 @@ func buildSecretId(ctx context.Context, secretName string) string { return secretName } -func getSecret(secretName string) map[string]interface{} { +func getSecret(ctx context.Context, secretName string) (map[string]interface{}, error) { mp := make(map[string]interface{}) - ctx := context.Background() client, err := secretmanager.NewClient(ctx) log.Debugf("client: %v", client) if err != nil { - log.Fatalf("failed to setup client: %v", err) + return nil, fmt.Errorf("failed to setup client: %v", err) } defer func(client *secretmanager.Client) { @@ -59,11 +59,11 @@ func getSecret(secretName string) map[string]interface{} { result, err := client.AccessSecretVersion(ctx, accessRequest) log.Debugf("result: %v", result) if err != nil { - log.Fatalf("failed to access secret version: %v", err) + return nil, fmt.Errorf("failed to access secret version: %v", err) } mp[cleanSecretName] = string(result.Payload.Data) - return mp + return mp, nil } type GcpSecretsManagerImp struct { @@ -73,6 +73,13 @@ func New() interfaces.SecretsManager { return &GcpSecretsManagerImp{} } -func (*GcpSecretsManagerImp) GetSecret(secretName string) map[string]interface{} { - return getSecret(secretName) +func (*GcpSecretsManagerImp) GetSecret(secretName string, timeout int) map[string]interface{} { + ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeout)*time.Second) + defer cancel() + + secret, err := getSecret(ctx, secretName) + if err != nil { + log.Errorf("failed to get secret: %v", err) + } + return secret } diff --git a/pkg/kubeseal-convert/handlers/gcpsecretsmanager/gcpsecretsmanager_test.go b/pkg/kubeseal-convert/handlers/gcpsecretsmanager/gcpsecretsmanager_test.go index c78ba5d..6df759f 100644 --- a/pkg/kubeseal-convert/handlers/gcpsecretsmanager/gcpsecretsmanager_test.go +++ b/pkg/kubeseal-convert/handlers/gcpsecretsmanager/gcpsecretsmanager_test.go @@ -39,7 +39,7 @@ func Test_getSecret(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got := getSecret(tt.args.secretName); !reflect.DeepEqual(got, tt.want) { + if got, _ := getSecret(context.TODO(), tt.args.secretName); !reflect.DeepEqual(got, tt.want) { t.Errorf("getSecret() = %v, want %v", got, tt.want) } }) diff --git a/pkg/kubeseal-convert/handlers/secretsmanager/secretsmanager.go b/pkg/kubeseal-convert/handlers/secretsmanager/secretsmanager.go index 0c8b280..31391ef 100644 --- a/pkg/kubeseal-convert/handlers/secretsmanager/secretsmanager.go +++ b/pkg/kubeseal-convert/handlers/secretsmanager/secretsmanager.go @@ -3,50 +3,56 @@ package secretsmanager import ( "context" "encoding/json" - - log "github.com/sirupsen/logrus" + "time" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/secretsmanager" + log "github.com/sirupsen/logrus" "github.com/eladleev/kubeseal-convert/pkg/kubeseal-convert/interfaces" ) -// TODO: Implement proper context func createConfig() aws.Config { - cfg, err := config.LoadDefaultConfig(context.TODO()) + cfg, err := config.LoadDefaultConfig(context.Background()) if err != nil { - log.Fatalf("Unable to load SDK config, %v", err) + log.Errorf("unable to load SDK config, %v", err) } return cfg } // getSecret wil get the secret into a map[string]interface{} as the return value may vary -func getSecret(svc *secretsmanager.Client, secretName string) map[string]interface{} { - r, err := svc.GetSecretValue(context.TODO(), &secretsmanager.GetSecretValueInput{SecretId: &secretName}) - log.Debugf("secretValue: %v", r) +func getSecret(ctx context.Context, svc *secretsmanager.Client, secretName string) (map[string]interface{}, error) { + r, err := svc.GetSecretValue(ctx, &secretsmanager.GetSecretValueInput{SecretId: &secretName}) if err != nil { - log.Fatal(err.Error()) + return nil, err } mp := make(map[string]interface{}) - error := json.Unmarshal([]byte(*r.SecretString), &mp) - if error != nil { - log.Fatalf("Unable to parse secret with err: %v", error) + err = json.Unmarshal([]byte(*r.SecretString), &mp) + if err != nil { + return nil, err } - return mp + return mp, nil } type SecretsManagerImp struct { + cfg aws.Config } func New() interfaces.SecretsManager { - return &SecretsManagerImp{} + return &SecretsManagerImp{cfg: createConfig()} } -func (*SecretsManagerImp) GetSecret(secretName string) map[string]interface{} { - cfg := createConfig() - svc := secretsmanager.NewFromConfig(cfg) - return getSecret(svc, secretName) +func (s *SecretsManagerImp) GetSecret(secretName string, timeout int) map[string]interface{} { + // Create a context with a timeout + ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeout)*time.Second) + defer cancel() + + svc := secretsmanager.NewFromConfig(s.cfg) + secret, err := getSecret(ctx, svc, secretName) + if err != nil { + log.Errorf("failed to get secret: %v", err) + } + return secret } diff --git a/pkg/kubeseal-convert/handlers/secretsmanager/secretsmanager_test.go b/pkg/kubeseal-convert/handlers/secretsmanager/secretsmanager_test.go index 32a98b9..68878fd 100644 --- a/pkg/kubeseal-convert/handlers/secretsmanager/secretsmanager_test.go +++ b/pkg/kubeseal-convert/handlers/secretsmanager/secretsmanager_test.go @@ -1,6 +1,7 @@ package secretsmanager import ( + "context" "reflect" "testing" @@ -21,7 +22,7 @@ func Test_getSecret(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got := getSecret(tt.args.svc, tt.args.secretName); !reflect.DeepEqual(got, tt.want) { + if got, _ := getSecret(context.TODO(), tt.args.svc, tt.args.secretName); !reflect.DeepEqual(got, tt.want) { t.Errorf("getSecret() = %v, want %v", got, tt.want) } }) diff --git a/pkg/kubeseal-convert/handlers/vault/vault.go b/pkg/kubeseal-convert/handlers/vault/vault.go index 00cdcc7..c0bc5d4 100644 --- a/pkg/kubeseal-convert/handlers/vault/vault.go +++ b/pkg/kubeseal-convert/handlers/vault/vault.go @@ -2,7 +2,9 @@ package vault import ( "context" + "fmt" "os" + "time" vault "github.com/hashicorp/vault/api" log "github.com/sirupsen/logrus" @@ -10,31 +12,31 @@ import ( "github.com/eladleev/kubeseal-convert/pkg/kubeseal-convert/interfaces" ) -// createClientContext creates a new Vault client with default config +// createClient creates a new Vault client with default config // and returns context and client -func createClientContext() (context.Context, *vault.Client) { +func createClient() (*vault.Client, error) { config := vault.DefaultConfig() config.Address = os.Getenv("VAULT_ADDR") client, err := vault.NewClient(config) if err != nil { - log.Fatalf("Unable to initialize a Vault client: %v", err) + return nil, fmt.Errorf("unable to initialize a Vault client: %v", err) } client.SetToken(os.Getenv("VAULT_TOKEN")) - return context.Background(), client + return client, nil } // getSecret get the Vault context, client, and secret name and retrieve the secret from Vault -func getSecret(ctx context.Context, client *vault.Client, secretName string) map[string]interface{} { +func getSecret(ctx context.Context, client *vault.Client, secretName string) (map[string]interface{}, error) { secret, err := client.KVv2("secret").Get(ctx, secretName) log.Debugf("secret: %v", secret) if err != nil { - log.Fatalf("Unable to read secret from the Vault: %v", err) + return nil, fmt.Errorf("unable to read secret from the Vault: %v", err) } - return secret.Data + return secret.Data, nil } type VaultImp struct { @@ -44,8 +46,21 @@ func New() interfaces.Vault { return &VaultImp{} } -func (*VaultImp) GetSecret(secretName string) map[string]interface{} { - ctx, cli := createClientContext() +func (*VaultImp) GetSecret(secretName string, timeout int) map[string]interface{} { + // Create a context with a timeout + ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeout)*time.Second) + defer cancel() + + cli, err := createClient() + if err != nil { + log.Fatalf("unable to initialize a Vault client: %v", err) + } + log.Debugf("ctx: %v", ctx) - return getSecret(ctx, cli, secretName) + + secret, err := getSecret(ctx, cli, secretName) + if err != nil { + log.Fatalf("failed to get secret: %v", err) + } + return secret } diff --git a/pkg/kubeseal-convert/handlers/vault/vault_test.go b/pkg/kubeseal-convert/handlers/vault/vault_test.go index 97b370e..b48f870 100644 --- a/pkg/kubeseal-convert/handlers/vault/vault_test.go +++ b/pkg/kubeseal-convert/handlers/vault/vault_test.go @@ -54,7 +54,7 @@ func Test_getSecret(t *testing.T) { defer ts.Close() // os.Setenv("VAULT_ADDR", ts.URL) - // ctx, client := createClientContext() + // ctx, client := createClient() // secret := getSecret(ctx, client, "my-secret") // if secret["username"] != "my-username" { diff --git a/pkg/kubeseal-convert/interfaces/azurekeyvault.go b/pkg/kubeseal-convert/interfaces/azurekeyvault.go index 81986ec..356367e 100644 --- a/pkg/kubeseal-convert/interfaces/azurekeyvault.go +++ b/pkg/kubeseal-convert/interfaces/azurekeyvault.go @@ -1,5 +1,5 @@ package interfaces type AzureKeyVault interface { - GetSecrets(vaultName string) map[string]interface{} + GetSecrets(vaultName string, timeout int) map[string]interface{} } diff --git a/pkg/kubeseal-convert/interfaces/gcpsecretsmanager.go b/pkg/kubeseal-convert/interfaces/gcpsecretsmanager.go index 9c87662..07b98c3 100644 --- a/pkg/kubeseal-convert/interfaces/gcpsecretsmanager.go +++ b/pkg/kubeseal-convert/interfaces/gcpsecretsmanager.go @@ -1,5 +1,5 @@ package interfaces type GcpSecretsManager interface { - GetSecret(secretName string) map[string]interface{} + GetSecret(secretName string, timeout int) map[string]interface{} } diff --git a/pkg/kubeseal-convert/interfaces/secretmanager.go b/pkg/kubeseal-convert/interfaces/secretmanager.go index a502f10..8015611 100644 --- a/pkg/kubeseal-convert/interfaces/secretmanager.go +++ b/pkg/kubeseal-convert/interfaces/secretmanager.go @@ -1,5 +1,5 @@ package interfaces type SecretsManager interface { - GetSecret(secretName string) map[string]interface{} + GetSecret(secretName string, timeout int) map[string]interface{} } diff --git a/pkg/kubeseal-convert/interfaces/vault.go b/pkg/kubeseal-convert/interfaces/vault.go index 91116df..b7faaac 100644 --- a/pkg/kubeseal-convert/interfaces/vault.go +++ b/pkg/kubeseal-convert/interfaces/vault.go @@ -1,5 +1,5 @@ package interfaces type Vault interface { - GetSecret(secretName string) map[string]interface{} + GetSecret(secretName string, timeout int) map[string]interface{} }