From f2279aa6707a257b2f55af9780b0bfc5485dbc5d Mon Sep 17 00:00:00 2001
From: "daniel.naude" <danieln@bob.co.za>
Date: Fri, 5 Apr 2024 11:12:31 +0200
Subject: [PATCH] Migrate secret manager package to aws sdk v2

---
 secrets_manager/secrets_manager.go | 89 ++++++++++++++++--------------
 1 file changed, 47 insertions(+), 42 deletions(-)

diff --git a/secrets_manager/secrets_manager.go b/secrets_manager/secrets_manager.go
index 85f4bda..1b14632 100644
--- a/secrets_manager/secrets_manager.go
+++ b/secrets_manager/secrets_manager.go
@@ -1,19 +1,21 @@
 package secrets_manager
 
 import (
+	"context"
 	"encoding/base64"
 	"encoding/json"
-	credentials2 "github.com/aws/aws-sdk-go/aws/credentials"
+	"errors"
 	"os"
 
 	"gitlab.bob.co.za/bob-public-utils/bobgroup-go-utils/logs"
 	"gitlab.bob.co.za/bob-public-utils/bobgroup-go-utils/struct_utils"
 
-	"github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/aws/awserr"
-	"github.com/aws/aws-sdk-go/aws/session"
-	"github.com/aws/aws-sdk-go/service/secretsmanager"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/config"
+	"github.com/aws/aws-sdk-go-v2/credentials"
+	"github.com/aws/aws-sdk-go-v2/service/secretsmanager"
 	"github.com/aws/aws-secretsmanager-caching-go/secretcache"
+	"github.com/aws/smithy-go"
 )
 
 type DatabaseCredentials struct {
@@ -26,17 +28,12 @@ type DatabaseCredentials struct {
 	ReadOnlyHost       string `json:"aurora_read_only_host"`
 }
 
-type S3UploadCredentials struct {
-	AccessKeyID string `json:"accessKeyID"`
-	SecretKey   string `json:"secretKey"`
-}
-
 var (
 	secretCache, _      = secretcache.New()
 	secretManagerRegion = "af-south-1"
 )
 
-var secretManagerSession *secretsmanager.SecretsManager
+var secretManagerClient *secretsmanager.Client
 
 func GetDatabaseCredentials(secretID string, isDebug bool) (DatabaseCredentials, error) {
 	secret, _ := GetSecret(secretID, isDebug)
@@ -48,54 +45,62 @@ func GetDatabaseCredentials(secretID string, isDebug bool) (DatabaseCredentials,
 	return credentials, nil
 }
 
-func GetS3UploadCredentials(secretID string, isDebug bool) (*credentials2.Credentials, error) {
+func GetS3UploadCredentials(secretID string, isDebug bool) (aws.Credentials, error) {
 	secret, _ := GetSecret(secretID, isDebug)
-	var credentials S3UploadCredentials
-	err := struct_utils.UnmarshalJSON([]byte(secret), &credentials)
+	var secretValue map[string]string
+	err := struct_utils.UnmarshalJSON([]byte(secret), &secretValue)
 	if err != nil {
-		return nil, err
+		return aws.Credentials{}, err
+	}
+
+	accessKeyID, ok := secretValue["AccessKeyID"]
+	if !ok {
+		return aws.Credentials{}, err
 	}
-	return credentials2.NewStaticCredentials(credentials.AccessKeyID, credentials.SecretKey, ""), nil
+
+	secretKey, ok := secretValue["SecretKey"]
+	if !ok {
+		return aws.Credentials{}, err
+	}
+
+	creds := aws.NewCredentialsCache(credentials.NewStaticCredentialsProvider(accessKeyID, secretKey, ""))
+
+	return creds.Retrieve(context.TODO())
 }
 
-// getSecretManagerSession Instantiates a new Secrets Manager client session
-func getSecretManagerSession(isDebug bool) (err error) {
-	// If a session already exists, use it
-	if secretManagerSession != nil {
+func instantiateSecretManagerClient(isDebug bool) (err error) {
+	// If a client already exists, use it
+	if secretManagerClient != nil {
 		return nil
 	}
 
-	awsSession, err := session.NewSession()
+	cfg, err := config.LoadDefaultConfig(context.TODO())
 	if err != nil {
 		return err
 	}
 
 	// Get local config
 	if isDebug && os.Getenv("ENVIRONMENT") != "" {
-		awsSession, err = session.NewSessionWithOptions(session.Options{
-			Config: aws.Config{
-				Region:                        aws.String("af-south-1"),
-				CredentialsChainVerboseErrors: aws.Bool(true),
-			},
-		})
+		cfg, err = config.LoadDefaultConfig(context.TODO(),
+			config.WithRegion(secretManagerRegion),
+		)
 		if err != nil {
 			return err
 		}
 	}
 
-	// Create a Secrets Manager client session
-	secretManagerSession = secretsmanager.New(awsSession, aws.NewConfig().WithRegion(secretManagerRegion))
+	// Create a Secrets Manager client
+	secretManagerClient = secretsmanager.NewFromConfig(cfg)
 
 	return nil
 }
 
 // logError Logs any errors returned by the Secrets Manager client
 func logError(err error) {
-	if aerr, ok := err.(awserr.Error); ok {
-		logs.Info(aerr.Code()+" %s", aerr.Error())
+	var apiErr *smithy.GenericAPIError
+	if errors.As(err, &apiErr) {
+		logs.Info(apiErr.Code+" %s", apiErr.Message)
 	} else {
-		// Print the error, cast err to awserr.Error to get the Code and
-		// Message from an error.
 		logs.Info(err.Error())
 	}
 }
@@ -108,7 +113,7 @@ func GetSecret(secretID string, isDebug bool) (string, string) {
 	}
 
 	// Create a Secrets Manager client
-	err := getSecretManagerSession(isDebug)
+	err := instantiateSecretManagerClient(isDebug)
 	if err != nil {
 		logs.Info("Could not create client: %+v", err)
 		return "", ""
@@ -120,7 +125,7 @@ func GetSecret(secretID string, isDebug bool) (string, string) {
 		VersionStage: aws.String("AWSCURRENT"), // VersionStage defaults to AWSCURRENT if unspecified
 	}
 
-	result, err := secretManagerSession.GetSecretValue(input)
+	result, err := secretManagerClient.GetSecretValue(context.TODO(), input)
 	if err != nil {
 		logError(err)
 		return "", ""
@@ -147,7 +152,7 @@ func GetSecret(secretID string, isDebug bool) (string, string) {
 // CreateSecret Creates a JSON marshaled "string secret" (can be expanded to cater for binary secrets should the need arise)
 func CreateSecret(secretID string, secret any, isDebug bool) (awsSecretID string, err error) {
 	// Create a Secrets Manager client
-	err = getSecretManagerSession(isDebug)
+	err = instantiateSecretManagerClient(isDebug)
 	if err != nil {
 		logs.Info("Could not create client: %+v", err)
 		return "", err
@@ -164,18 +169,18 @@ func CreateSecret(secretID string, secret any, isDebug bool) (awsSecretID string
 		SecretString: aws.String(string(secretStr)),
 	}
 
-	result, err := secretManagerSession.CreateSecret(input)
+	result, err := secretManagerClient.CreateSecret(context.TODO(), input)
 	if err != nil {
 		logError(err)
 		return "", err
 	}
 
-	return aws.StringValue(result.Name), nil
+	return aws.ToString(result.Name), nil
 }
 
 func DeleteSecret(secretID string, forceWithoutRecovery bool, isDebug bool) error {
 	// Create a Secrets Manager client
-	err := getSecretManagerSession(isDebug)
+	err := instantiateSecretManagerClient(isDebug)
 	if err != nil {
 		logs.Info("Could not create client: %+v", err)
 		return err
@@ -187,7 +192,7 @@ func DeleteSecret(secretID string, forceWithoutRecovery bool, isDebug bool) erro
 		ForceDeleteWithoutRecovery: aws.Bool(forceWithoutRecovery),
 	}
 
-	_, err = secretManagerSession.DeleteSecret(input)
+	_, err = secretManagerClient.DeleteSecret(context.TODO(), input)
 	if err != nil {
 		logError(err)
 		return err
@@ -199,7 +204,7 @@ func DeleteSecret(secretID string, forceWithoutRecovery bool, isDebug bool) erro
 // UpdateSecret Updates an exising secret
 func UpdateSecret(secretID string, secret any, isDebug bool) error {
 	// Create a Secrets Manager client
-	err := getSecretManagerSession(isDebug)
+	err := instantiateSecretManagerClient(isDebug)
 	if err != nil {
 		logs.Info("Could not create client: %+v", err)
 		return err
@@ -216,7 +221,7 @@ func UpdateSecret(secretID string, secret any, isDebug bool) error {
 		SecretString: aws.String(string(secretStr)),
 	}
 
-	_, err = secretManagerSession.UpdateSecret(input)
+	_, err = secretManagerClient.UpdateSecret(context.TODO(), input)
 	if err != nil {
 		logError(err)
 		return err
-- 
GitLab