github.com/defang-io/defang/src@v0.0.0-20240505002154-bdf411911834/pkg/clouds/aws/secrets_test.go (about)

     1  //go:build integration
     2  
     3  package aws
     4  
     5  import (
     6  	"context"
     7  	"errors"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/aws/aws-sdk-go-v2/aws"
    12  	"github.com/aws/aws-sdk-go-v2/service/ssm"
    13  	"github.com/aws/aws-sdk-go-v2/service/ssm/types"
    14  	"github.com/defang-io/defang/src/pkg"
    15  	"github.com/google/uuid"
    16  )
    17  
    18  func isErrCodeNotFound(err error) bool {
    19  	var e *types.ParameterNotFound
    20  	return errors.As(err, &e)
    21  }
    22  
    23  func TestPutSecret(t *testing.T) {
    24  	a := Aws{Region: Region(pkg.Getenv("AWS_REGION", "us-west-2"))}
    25  
    26  	ctx := context.Background()
    27  	cfg, err := a.LoadConfig(ctx)
    28  	if err != nil {
    29  		t.Fatal(err)
    30  	}
    31  
    32  	// Create an instance of AWS SSM
    33  	svc := ssm.NewFromConfig(cfg)
    34  
    35  	// Create random secret name and value
    36  	name := uuid.NewString()
    37  	value := uuid.NewString()
    38  	secretId := name // caller should have added any prefix
    39  
    40  	exist, err := a.IsValidSecret(ctx, name)
    41  	if err != nil {
    42  		t.Fatal(err)
    43  	}
    44  	if exist {
    45  		t.Fatal("secret should not exist")
    46  	}
    47  
    48  	err = a.PutSecret(ctx, name, value)
    49  	if err != nil {
    50  		t.Fatal(err)
    51  	}
    52  	// Cleanup after test
    53  	defer svc.DeleteParameter(ctx, &ssm.DeleteParameterInput{
    54  		Name: &secretId,
    55  	})
    56  
    57  	gsv, err := svc.GetParameter(ctx, &ssm.GetParameterInput{
    58  		Name:           &secretId,
    59  		WithDecryption: aws.Bool(true),
    60  	})
    61  	if err != nil {
    62  		t.Fatal(err)
    63  	}
    64  	if value != *gsv.Parameter.Value {
    65  		t.Fatalf("expected %s, got %s", value, *gsv.Parameter.Value)
    66  	}
    67  
    68  	exist, err = a.IsValidSecret(ctx, name)
    69  	if err != nil {
    70  		t.Fatal(err)
    71  	}
    72  	if !exist {
    73  		t.Fatal("secret should exist")
    74  	}
    75  
    76  	// Check that the secret is in the list
    77  	ls, err := a.ListSecrets(ctx)
    78  	if err != nil {
    79  		t.Fatal(err)
    80  	}
    81  	found := false
    82  	for _, s := range ls {
    83  		if s == name {
    84  			found = true
    85  			break
    86  		}
    87  	}
    88  	if !found {
    89  		t.Fatalf("expected %s in list, got %v", name, ls)
    90  	}
    91  
    92  	// Overwrite secret with a new value
    93  	err = a.PutSecret(ctx, name, "new value")
    94  	if err != nil {
    95  		t.Fatal(err)
    96  	}
    97  
    98  	// Overwrite secret with empty; this should delete the secret
    99  	err = a.DeleteSecrets(ctx, name)
   100  	if err != nil {
   101  		t.Fatal(err)
   102  	}
   103  
   104  	// Check that the secret is deleted
   105  	_, err = svc.GetParameter(ctx, &ssm.GetParameterInput{
   106  		Name: &secretId,
   107  	})
   108  	if !isErrCodeNotFound(err) {
   109  		t.Fatalf("expected ErrCodeParameterNotFound, got %v", err)
   110  	}
   111  
   112  	// Delete the secret again; this should return NotFound
   113  	err = a.DeleteSecrets(ctx, name)
   114  	if !isErrCodeNotFound(err) {
   115  		t.Fatalf("expected ErrCodeParameterNotFound, got %v", err)
   116  	}
   117  
   118  	// Check that the secret is not in the list; delete is lazy so retry for up to 5 seconds
   119  	for i := 0; i < 5; i++ {
   120  		ls, err = a.ListSecrets(ctx)
   121  		if err != nil {
   122  			t.Fatal(err)
   123  		}
   124  		found = false
   125  		for _, s := range ls {
   126  			if s == name {
   127  				found = true
   128  				break
   129  			}
   130  		}
   131  		if !found {
   132  			break
   133  		}
   134  		time.Sleep(time.Second)
   135  	}
   136  	if found {
   137  		t.Fatalf("expected %s not in list, got %v", name, ls)
   138  	}
   139  }