From 5217cdc624bb374c23949711d5d0c2d498f4bd91 Mon Sep 17 00:00:00 2001 From: Tim Holm Date: Wed, 24 May 2023 16:48:00 +1000 Subject: [PATCH 1/4] Add secret import capability --- cloud/aws/deploy/config/config.go | 6 +++ cloud/aws/deploy/secret/secretsmanager.go | 64 ++++++++++++++++++++--- cloud/aws/deploy/up.go | 9 ++++ 3 files changed, 71 insertions(+), 8 deletions(-) diff --git a/cloud/aws/deploy/config/config.go b/cloud/aws/deploy/config/config.go index c059a0e1d..6c0bb2c52 100644 --- a/cloud/aws/deploy/config/config.go +++ b/cloud/aws/deploy/config/config.go @@ -22,8 +22,14 @@ import ( "github.com/nitrictech/nitric/cloud/common/deploy/config" ) +type AwsImports struct { + // A map of nitric names to ARNs + Secrets map[string]string +} + type AwsConfig struct { ScheduleTimezone string `mapstructure:"schedule-timezone,omitempty"` + Imports AwsImports config.AbstractConfig[*AwsConfigItem] } diff --git a/cloud/aws/deploy/secret/secretsmanager.go b/cloud/aws/deploy/secret/secretsmanager.go index b89c1de7b..b9b58e539 100644 --- a/cloud/aws/deploy/secret/secretsmanager.go +++ b/cloud/aws/deploy/secret/secretsmanager.go @@ -17,6 +17,10 @@ package secret import ( + "context" + + "github.com/aws/aws-sdk-go-v2/service/resourcegroupstaggingapi" + "github.com/aws/aws-sdk-go/aws" common "github.com/nitrictech/nitric/cloud/common/deploy/tags" v1 "github.com/nitrictech/nitric/core/pkg/api/nitric/deploy/v1" "github.com/pulumi/pulumi-aws/sdk/v5/go/aws/secretsmanager" @@ -31,7 +35,10 @@ type SecretsManagerSecret struct { type SecretsManagerSecretArgs struct { StackID pulumi.StringInput - Secret *v1.Secret + // Import an existing secret + Import string + Secret *v1.Secret + Client *resourcegroupstaggingapi.Client } // Create a new SecretsManager secret @@ -45,14 +52,55 @@ func NewSecretsManagerSecret(ctx *pulumi.Context, name string, args *SecretsMana return nil, err } - sec, err := secretsmanager.NewSecret(ctx, name, &secretsmanager.SecretArgs{ - Tags: common.Tags(ctx, args.StackID, name), - }) - if err != nil { - return nil, err - } + if args.Import != "" { + secretLookup, err := secretsmanager.LookupSecret(ctx, &secretsmanager.LookupSecretArgs{ + Arn: aws.String(args.Import), + }) + if err != nil { + return nil, err + } - res.SecretsManager = sec + // apply nitric tags + // This will apply nitric tags for resource resolution + _ = args.StackID.ToStringOutput().ApplyT(func(stackId string) (bool, error) { + _, err := args.Client.TagResources(context.TODO(), &resourcegroupstaggingapi.TagResourcesInput{ + ResourceARNList: []string{secretLookup.Arn}, + Tags: map[string]string{ + "x-nitric-project": ctx.Project(), + "x-nitric-name": name, + "x-nitric-stack-name": ctx.Stack(), + "x-nitric-stack": stackId, + }, + }) + + if err != nil { + return false, err + } + + return true, nil + }) + + // import an existing secret + res.SecretsManager, err = secretsmanager.GetSecret( + ctx, + name, + pulumi.ID(secretLookup.Id), + nil, + // not our resource so we'll keep it around + pulumi.RetainOnDelete(true), + ) + if err != nil { + return nil, err + } + } else { + // create a new secret + res.SecretsManager, err = secretsmanager.NewSecret(ctx, name, &secretsmanager.SecretArgs{ + Tags: common.Tags(ctx, args.StackID, name), + }) + if err != nil { + return nil, err + } + } return res, nil } diff --git a/cloud/aws/deploy/up.go b/cloud/aws/deploy/up.go index 3b647be24..1505eaaf8 100644 --- a/cloud/aws/deploy/up.go +++ b/cloud/aws/deploy/up.go @@ -24,6 +24,7 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/lambda" + "github.com/aws/aws-sdk-go/service/resourcegroupstaggingapi" "github.com/getkin/kin-openapi/openapi3" "github.com/nitrictech/nitric/cloud/aws/deploy/api" "github.com/nitrictech/nitric/cloud/aws/deploy/bucket" @@ -76,6 +77,7 @@ func (d *DeployServer) Up(request *deploy.DeployUpRequest, stream deploy.DeployS SharedConfigState: session.SharedConfigEnable, })) lambdaClient := lambda.New(sess, &aws.Config{Region: aws.String(details.Region)}) + resourceTaggingClient := resourcegroupstaggingapi.New(sess) pulumiStack, err := auto.UpsertStackInlineSource(context.TODO(), details.FullStackName, details.Project, func(ctx *pulumi.Context) error { principals := map[v1.ResourceType]map[string]*iam.Role{} @@ -105,9 +107,16 @@ func (d *DeployServer) Up(request *deploy.DeployUpRequest, stream deploy.DeployS for _, res := range request.Spec.Resources { switch c := res.Config.(type) { case *deploy.Resource_Secret: + importArn := "" + + if config.Imports.Secrets != nil { + importArn = config.Imports.Secrets[res.Name] + } + secrets[res.Name], err = secret.NewSecretsManagerSecret(ctx, res.Name, &secret.SecretsManagerSecretArgs{ StackID: stackID, Secret: c.Secret, + Import: importArn, }) if err != nil { return err From 0fd774e7dc0636af505b25eb0b519dc6f2d72847 Mon Sep 17 00:00:00 2001 From: Tim Holm Date: Wed, 24 May 2023 17:10:07 +1000 Subject: [PATCH 2/4] update secret retrieval --- cloud/aws/deploy/secret/secretsmanager.go | 14 ++++++-------- cloud/aws/deploy/up.go | 1 + cloud/aws/runtime/secret/secrets_manager.go | 8 +++++++- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/cloud/aws/deploy/secret/secretsmanager.go b/cloud/aws/deploy/secret/secretsmanager.go index b9b58e539..2c289b81a 100644 --- a/cloud/aws/deploy/secret/secretsmanager.go +++ b/cloud/aws/deploy/secret/secretsmanager.go @@ -17,10 +17,8 @@ package secret import ( - "context" - - "github.com/aws/aws-sdk-go-v2/service/resourcegroupstaggingapi" "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/resourcegroupstaggingapi" common "github.com/nitrictech/nitric/cloud/common/deploy/tags" v1 "github.com/nitrictech/nitric/core/pkg/api/nitric/deploy/v1" "github.com/pulumi/pulumi-aws/sdk/v5/go/aws/secretsmanager" @@ -38,7 +36,7 @@ type SecretsManagerSecretArgs struct { // Import an existing secret Import string Secret *v1.Secret - Client *resourcegroupstaggingapi.Client + Client *resourcegroupstaggingapi.ResourceGroupsTaggingAPI } // Create a new SecretsManager secret @@ -63,14 +61,14 @@ func NewSecretsManagerSecret(ctx *pulumi.Context, name string, args *SecretsMana // apply nitric tags // This will apply nitric tags for resource resolution _ = args.StackID.ToStringOutput().ApplyT(func(stackId string) (bool, error) { - _, err := args.Client.TagResources(context.TODO(), &resourcegroupstaggingapi.TagResourcesInput{ - ResourceARNList: []string{secretLookup.Arn}, - Tags: map[string]string{ + _, err := args.Client.TagResources(&resourcegroupstaggingapi.TagResourcesInput{ + ResourceARNList: aws.StringSlice([]string{secretLookup.Arn}), + Tags: aws.StringMap(map[string]string{ "x-nitric-project": ctx.Project(), "x-nitric-name": name, "x-nitric-stack-name": ctx.Stack(), "x-nitric-stack": stackId, - }, + }), }) if err != nil { diff --git a/cloud/aws/deploy/up.go b/cloud/aws/deploy/up.go index 1505eaaf8..c2d6e46f7 100644 --- a/cloud/aws/deploy/up.go +++ b/cloud/aws/deploy/up.go @@ -117,6 +117,7 @@ func (d *DeployServer) Up(request *deploy.DeployUpRequest, stream deploy.DeployS StackID: stackID, Secret: c.Secret, Import: importArn, + Client: resourceTaggingClient, }) if err != nil { return err diff --git a/cloud/aws/runtime/secret/secrets_manager.go b/cloud/aws/runtime/secret/secrets_manager.go index 05f20a901..d75ec78bd 100644 --- a/cloud/aws/runtime/secret/secrets_manager.go +++ b/cloud/aws/runtime/secret/secrets_manager.go @@ -153,6 +153,12 @@ func (s *secretsManagerSecretService) Access(ctx context.Context, sv *secret.Sec ) } + returnValue := result.SecretBinary + + if returnValue == nil && result.SecretString != nil { + returnValue = []byte(*result.SecretString) + } + return &secret.SecretAccessResponse{ SecretVersion: &secret.SecretVersion{ Secret: &secret.Secret{ @@ -160,7 +166,7 @@ func (s *secretsManagerSecretService) Access(ctx context.Context, sv *secret.Sec }, Version: *result.VersionId, }, - Value: result.SecretBinary, + Value: returnValue, }, nil } From ec66e4c7d406e0327f51c2967f9e74de22b34c1d Mon Sep 17 00:00:00 2001 From: Tim Holm Date: Wed, 24 May 2023 17:21:58 +1000 Subject: [PATCH 3/4] fmt --- cloud/aws/deploy/secret/secretsmanager.go | 1 - 1 file changed, 1 deletion(-) diff --git a/cloud/aws/deploy/secret/secretsmanager.go b/cloud/aws/deploy/secret/secretsmanager.go index 2c289b81a..5e64e6d37 100644 --- a/cloud/aws/deploy/secret/secretsmanager.go +++ b/cloud/aws/deploy/secret/secretsmanager.go @@ -70,7 +70,6 @@ func NewSecretsManagerSecret(ctx *pulumi.Context, name string, args *SecretsMana "x-nitric-stack": stackId, }), }) - if err != nil { return false, err } From 3f8c58d6df78e4c9d6fe6d4ae467c543b8b8bbd8 Mon Sep 17 00:00:00 2001 From: Tim Holm Date: Thu, 25 May 2023 09:08:20 +1000 Subject: [PATCH 4/4] change Imports -> Import --- cloud/aws/deploy/config/config.go | 2 +- cloud/aws/deploy/up.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cloud/aws/deploy/config/config.go b/cloud/aws/deploy/config/config.go index 6c0bb2c52..9c97e986f 100644 --- a/cloud/aws/deploy/config/config.go +++ b/cloud/aws/deploy/config/config.go @@ -29,7 +29,7 @@ type AwsImports struct { type AwsConfig struct { ScheduleTimezone string `mapstructure:"schedule-timezone,omitempty"` - Imports AwsImports + Import AwsImports config.AbstractConfig[*AwsConfigItem] } diff --git a/cloud/aws/deploy/up.go b/cloud/aws/deploy/up.go index c2d6e46f7..44aa69fd0 100644 --- a/cloud/aws/deploy/up.go +++ b/cloud/aws/deploy/up.go @@ -109,8 +109,8 @@ func (d *DeployServer) Up(request *deploy.DeployUpRequest, stream deploy.DeployS case *deploy.Resource_Secret: importArn := "" - if config.Imports.Secrets != nil { - importArn = config.Imports.Secrets[res.Name] + if config.Import.Secrets != nil { + importArn = config.Import.Secrets[res.Name] } secrets[res.Name], err = secret.NewSecretsManagerSecret(ctx, res.Name, &secret.SecretsManagerSecretArgs{