diff --git a/docs/stackit_secrets-manager_instance_create.md b/docs/stackit_secrets-manager_instance_create.md index 379de7785..65108008a 100644 --- a/docs/stackit_secrets-manager_instance_create.md +++ b/docs/stackit_secrets-manager_instance_create.md @@ -18,14 +18,21 @@ stackit secrets-manager instance create [flags] Create a Secrets Manager instance with name "my-instance" and specify IP range which is allowed to access it $ stackit secrets-manager instance create --name my-instance --acl 1.2.3.0/24 + + Create a Secrets Manager instance with name "my-instance" and configure KMS key options + $ stackit secrets-manager instance create --name my-instance --kms-key-id key-id --kms-keyring-id keyring-id --kms-key-version 1 --kms-service-account-email my-service-account-1234567@sa.stackit.cloud ``` ### Options ``` - --acl strings List of IP networks in CIDR notation which are allowed to access this instance (default []) - -h, --help Help for "stackit secrets-manager instance create" - -n, --name string Instance name + --acl strings List of IP networks in CIDR notation which are allowed to access this instance (default []) + -h, --help Help for "stackit secrets-manager instance create" + --kms-key-id string ID of the KMS key to use for encryption + --kms-key-version int Version of the KMS key + --kms-keyring-id string ID of the KMS key ring + --kms-service-account-email string Service account email for KMS access + -n, --name string Instance name ``` ### Options inherited from parent commands diff --git a/docs/stackit_secrets-manager_instance_update.md b/docs/stackit_secrets-manager_instance_update.md index cf40d3c1a..312588314 100644 --- a/docs/stackit_secrets-manager_instance_update.md +++ b/docs/stackit_secrets-manager_instance_update.md @@ -15,13 +15,20 @@ stackit secrets-manager instance update INSTANCE_ID [flags] ``` Update the range of IPs allowed to access a Secrets Manager instance with ID "xxx" $ stackit secrets-manager instance update xxx --acl 1.2.3.0/24 + + Update the KMS key settings of a Secrets Manager instance with ID "xxx" + $ stackit secrets-manager instance update xxx --kms-key-id key-id --kms-keyring-id keyring-id --kms-key-version 1 --kms-service-account-email my-service-account-1234567@sa.stackit.cloud ``` ### Options ``` - --acl strings List of IP networks in CIDR notation which are allowed to access this instance (default []) - -h, --help Help for "stackit secrets-manager instance update" + --acl strings List of IP networks in CIDR notation which are allowed to access this instance (default []) + -h, --help Help for "stackit secrets-manager instance update" + --kms-key-id string ID of the KMS key to use for encryption + --kms-key-version int Version of the KMS key + --kms-keyring-id string ID of the KMS key ring + --kms-service-account-email string Service account email for KMS access ``` ### Options inherited from parent commands diff --git a/internal/cmd/secrets-manager/instance/create/create.go b/internal/cmd/secrets-manager/instance/create/create.go index 0c6d8420b..12e9b2099 100644 --- a/internal/cmd/secrets-manager/instance/create/create.go +++ b/internal/cmd/secrets-manager/instance/create/create.go @@ -23,6 +23,11 @@ import ( const ( instanceNameFlag = "name" aclFlag = "acl" + + kmsKeyIdFlag = "kms-key-id" + kmsKeyringIdFlag = "kms-keyring-id" + kmsKeyVersionFlag = "kms-key-version" + kmsServiceAccountEmailFlag = "kms-service-account-email" ) type inputModel struct { @@ -30,6 +35,11 @@ type inputModel struct { InstanceName *string Acls *[]string + + KmsKeyId *string + KmsKeyringId *string + KmsKeyVersion *int64 + KmsServiceAccountEmail *string } func NewCmd(params *types.CmdParams) *cobra.Command { @@ -45,6 +55,9 @@ func NewCmd(params *types.CmdParams) *cobra.Command { examples.NewExample( `Create a Secrets Manager instance with name "my-instance" and specify IP range which is allowed to access it`, `$ stackit secrets-manager instance create --name my-instance --acl 1.2.3.0/24`), + examples.NewExample( + `Create a Secrets Manager instance with name "my-instance" and configure KMS key options`, + `$ stackit secrets-manager instance create --name my-instance --kms-key-id key-id --kms-keyring-id keyring-id --kms-key-version 1 --kms-service-account-email my-service-account-1234567@sa.stackit.cloud`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() @@ -103,8 +116,15 @@ func configureFlags(cmd *cobra.Command) { cmd.Flags().StringP(instanceNameFlag, "n", "", "Instance name") cmd.Flags().Var(flags.CIDRSliceFlag(), aclFlag, "List of IP networks in CIDR notation which are allowed to access this instance") + cmd.Flags().String(kmsKeyIdFlag, "", "ID of the KMS key to use for encryption") + cmd.Flags().String(kmsKeyringIdFlag, "", "ID of the KMS key ring") + cmd.Flags().Int64(kmsKeyVersionFlag, 0, "Version of the KMS key") + cmd.Flags().String(kmsServiceAccountEmailFlag, "", "Service account email for KMS access") + err := flags.MarkFlagsRequired(cmd, instanceNameFlag) cobra.CheckErr(err) + + cmd.MarkFlagsRequiredTogether(kmsKeyIdFlag, kmsKeyringIdFlag, kmsKeyVersionFlag, kmsServiceAccountEmailFlag) } func parseInput(p *print.Printer, cmd *cobra.Command, _ []string) (*inputModel, error) { @@ -114,9 +134,13 @@ func parseInput(p *print.Printer, cmd *cobra.Command, _ []string) (*inputModel, } model := inputModel{ - GlobalFlagModel: globalFlags, - InstanceName: flags.FlagToStringPointer(p, cmd, instanceNameFlag), - Acls: flags.FlagToStringSlicePointer(p, cmd, aclFlag), + GlobalFlagModel: globalFlags, + InstanceName: flags.FlagToStringPointer(p, cmd, instanceNameFlag), + Acls: flags.FlagToStringSlicePointer(p, cmd, aclFlag), + KmsKeyId: flags.FlagToStringPointer(p, cmd, kmsKeyIdFlag), + KmsKeyringId: flags.FlagToStringPointer(p, cmd, kmsKeyringIdFlag), + KmsKeyVersion: flags.FlagToInt64Pointer(p, cmd, kmsKeyVersionFlag), + KmsServiceAccountEmail: flags.FlagToStringPointer(p, cmd, kmsServiceAccountEmailFlag), } p.DebugInputModel(model) @@ -126,9 +150,20 @@ func parseInput(p *print.Printer, cmd *cobra.Command, _ []string) (*inputModel, func buildCreateInstanceRequest(ctx context.Context, model *inputModel, apiClient *secretsmanager.APIClient) secretsmanager.ApiCreateInstanceRequest { req := apiClient.CreateInstance(ctx, model.ProjectId) - req = req.CreateInstancePayload(secretsmanager.CreateInstancePayload{ + payload := secretsmanager.CreateInstancePayload{ Name: model.InstanceName, - }) + } + + if model.KmsKeyId != nil { + payload.KmsKey = &secretsmanager.KmsKeyPayload{ + KeyId: model.KmsKeyId, + KeyRingId: model.KmsKeyringId, + KeyVersion: model.KmsKeyVersion, + ServiceAccountEmail: model.KmsServiceAccountEmail, + } + } + + req = req.CreateInstancePayload(payload) return req } diff --git a/internal/cmd/secrets-manager/instance/create/create_test.go b/internal/cmd/secrets-manager/instance/create/create_test.go index 4cef0d887..e4c6cedda 100644 --- a/internal/cmd/secrets-manager/instance/create/create_test.go +++ b/internal/cmd/secrets-manager/instance/create/create_test.go @@ -25,6 +25,13 @@ var testClient = &secretsmanager.APIClient{} var testProjectId = uuid.NewString() var testInstanceId = uuid.NewString() +const ( + testKmsKeyId = "key-id" + testKmsKeyringId = "keyring-id" + testKmsKeyVersion = int64(1) + testKmsServiceAccountEmail = "my-service-account-1234567@sa.stackit.cloud" +) + func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]string { flagValues := map[string]string{ projectIdFlag: testProjectId, @@ -162,6 +169,24 @@ func TestParseInput(t *testing.T) { *model.Acls = append(*model.Acls, "1.2.3.4/32") }), }, + { + description: "kms flags", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, aclFlag) + flagValues[kmsKeyIdFlag] = testKmsKeyId + flagValues[kmsKeyringIdFlag] = testKmsKeyringId + flagValues[kmsKeyVersionFlag] = "1" + flagValues[kmsServiceAccountEmailFlag] = testKmsServiceAccountEmail + }), + isValid: true, + expectedModel: fixtureInputModel(func(model *inputModel) { + model.Acls = nil + model.KmsKeyId = utils.Ptr(testKmsKeyId) + model.KmsKeyringId = utils.Ptr(testKmsKeyringId) + model.KmsKeyVersion = utils.Ptr(testKmsKeyVersion) + model.KmsServiceAccountEmail = utils.Ptr(testKmsServiceAccountEmail) + }), + }, { description: "project id missing", flagValues: fixtureFlagValues(func(flagValues map[string]string) { @@ -205,6 +230,28 @@ func TestBuildCreateInstanceRequest(t *testing.T) { model: fixtureInputModel(), expectedRequest: fixtureRequest(), }, + { + description: "with kms", + model: fixtureInputModel(func(model *inputModel) { + model.Acls = nil + model.KmsKeyId = utils.Ptr(testKmsKeyId) + model.KmsKeyringId = utils.Ptr(testKmsKeyringId) + model.KmsKeyVersion = utils.Ptr(testKmsKeyVersion) + model.KmsServiceAccountEmail = utils.Ptr(testKmsServiceAccountEmail) + }), + expectedRequest: fixtureRequest(func(request *secretsmanager.ApiCreateInstanceRequest) { + payload := secretsmanager.CreateInstancePayload{ + Name: utils.Ptr("example"), + KmsKey: &secretsmanager.KmsKeyPayload{ + KeyId: utils.Ptr(testKmsKeyId), + KeyRingId: utils.Ptr(testKmsKeyringId), + KeyVersion: utils.Ptr(testKmsKeyVersion), + ServiceAccountEmail: utils.Ptr(testKmsServiceAccountEmail), + }, + } + *request = (*request).CreateInstancePayload(payload) + }), + }, } for _, tt := range tests { diff --git a/internal/cmd/secrets-manager/instance/describe/describe.go b/internal/cmd/secrets-manager/instance/describe/describe.go index bbd162bff..75c8cbd7c 100644 --- a/internal/cmd/secrets-manager/instance/describe/describe.go +++ b/internal/cmd/secrets-manager/instance/describe/describe.go @@ -128,6 +128,17 @@ func outputResult(p *print.Printer, outputFormat string, instance *secretsmanage table.AddSeparator() table.AddRow("CREATION DATE", utils.PtrString(instance.CreationStartDate)) table.AddSeparator() + kmsKey := instance.KmsKey + showKms := kmsKey != nil && (kmsKey.KeyId != nil || kmsKey.KeyRingId != nil || kmsKey.KeyVersion != nil || kmsKey.ServiceAccountEmail != nil) + if showKms { + table.AddRow("KMS KEY ID", utils.PtrString(kmsKey.KeyId)) + table.AddSeparator() + table.AddRow("KMS KEYRING ID", utils.PtrString(kmsKey.KeyRingId)) + table.AddSeparator() + table.AddRow("KMS KEY VERSION", utils.PtrString(kmsKey.KeyVersion)) + table.AddSeparator() + table.AddRow("KMS SERVICE ACCOUNT EMAIL", utils.PtrString(kmsKey.ServiceAccountEmail)) + } // Only show ACL if it's present and not empty if aclList.Acls != nil && len(*aclList.Acls) > 0 { var cidrs []string @@ -136,6 +147,9 @@ func outputResult(p *print.Printer, outputFormat string, instance *secretsmanage cidrs = append(cidrs, *acl.Cidr) } + if showKms { + table.AddSeparator() + } table.AddRow("ACL", strings.Join(cidrs, ",")) } err := table.Display(p) diff --git a/internal/cmd/secrets-manager/instance/describe/describe_test.go b/internal/cmd/secrets-manager/instance/describe/describe_test.go index c1e3e0bb7..fb36f10bb 100644 --- a/internal/cmd/secrets-manager/instance/describe/describe_test.go +++ b/internal/cmd/secrets-manager/instance/describe/describe_test.go @@ -9,6 +9,7 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/print" "github.com/stackitcloud/stackit-cli/internal/pkg/testutils" + "github.com/stackitcloud/stackit-cli/internal/pkg/utils" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" @@ -247,6 +248,21 @@ func TestOutputResult(t *testing.T) { }, wantErr: false, }, + { + name: "instance with kms key", + args: args{ + instance: &secretsmanager.Instance{ + KmsKey: &secretsmanager.KmsKeyPayload{ + KeyId: utils.Ptr("key-id"), + KeyRingId: utils.Ptr("keyring-id"), + KeyVersion: utils.Ptr(int64(1)), + ServiceAccountEmail: utils.Ptr("my-service-account-1234567@sa.stackit.cloud"), + }, + }, + aclList: &secretsmanager.ListACLsResponse{}, + }, + wantErr: false, + }, } p := print.NewPrinter() p.Cmd = NewCmd(&types.CmdParams{Printer: p}) diff --git a/internal/cmd/secrets-manager/instance/update/update.go b/internal/cmd/secrets-manager/instance/update/update.go index 58786ffd6..8870ebe80 100644 --- a/internal/cmd/secrets-manager/instance/update/update.go +++ b/internal/cmd/secrets-manager/instance/update/update.go @@ -25,6 +25,11 @@ const ( instanceIdArg = "INSTANCE_ID" aclFlag = "acl" + + kmsKeyIdFlag = "kms-key-id" + kmsKeyringIdFlag = "kms-keyring-id" + kmsKeyVersionFlag = "kms-key-version" + kmsServiceAccountEmailFlag = "kms-service-account-email" ) type inputModel struct { @@ -32,6 +37,11 @@ type inputModel struct { InstanceId string Acls *[]string + + KmsKeyId *string + KmsKeyringId *string + KmsKeyVersion *int64 + KmsServiceAccountEmail *string } func NewCmd(params *types.CmdParams) *cobra.Command { @@ -44,6 +54,9 @@ func NewCmd(params *types.CmdParams) *cobra.Command { examples.NewExample( `Update the range of IPs allowed to access a Secrets Manager instance with ID "xxx"`, "$ stackit secrets-manager instance update xxx --acl 1.2.3.0/24"), + examples.NewExample( + `Update the KMS key settings of a Secrets Manager instance with ID "xxx"`, + "$ stackit secrets-manager instance update xxx --kms-key-id key-id --kms-keyring-id keyring-id --kms-key-version 1 --kms-service-account-email my-service-account-1234567@sa.stackit.cloud"), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() @@ -62,6 +75,9 @@ func NewCmd(params *types.CmdParams) *cobra.Command { if err != nil { params.Printer.Debug(print.ErrorLevel, "get instance name: %v", err) instanceLabel = model.InstanceId + if model.KmsKeyId != nil { + return fmt.Errorf("get instance name: %w", err) + } } prompt := fmt.Sprintf("Are you sure you want to update instance %q?", instanceLabel) @@ -71,8 +87,15 @@ func NewCmd(params *types.CmdParams) *cobra.Command { } // Call API - req := buildRequest(ctx, model, apiClient) - err = req.Execute() + req := buildRequest(ctx, model, instanceLabel, apiClient) + switch request := req.(type) { + case secretsmanager.ApiUpdateInstanceRequest: + err = request.Execute() + case secretsmanager.ApiUpdateACLsRequest: + err = request.Execute() + default: + err = fmt.Errorf("unknown request type") + } if err != nil { return fmt.Errorf("update Secrets Manager instance: %w", err) } @@ -87,6 +110,15 @@ func NewCmd(params *types.CmdParams) *cobra.Command { func configureFlags(cmd *cobra.Command) { cmd.Flags().Var(flags.CIDRSliceFlag(), aclFlag, "List of IP networks in CIDR notation which are allowed to access this instance") + + cmd.Flags().String(kmsKeyIdFlag, "", "ID of the KMS key to use for encryption") + cmd.Flags().String(kmsKeyringIdFlag, "", "ID of the KMS key ring") + cmd.Flags().Int64(kmsKeyVersionFlag, 0, "Version of the KMS key") + cmd.Flags().String(kmsServiceAccountEmailFlag, "", "Service account email for KMS access") + + cmd.MarkFlagsRequiredTogether(kmsKeyIdFlag, kmsKeyringIdFlag, kmsKeyVersionFlag, kmsServiceAccountEmailFlag) + cmd.MarkFlagsMutuallyExclusive(aclFlag, kmsKeyIdFlag) + cmd.MarkFlagsOneRequired(aclFlag, kmsKeyIdFlag) } func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inputModel, error) { @@ -99,21 +131,47 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu acls := flags.FlagToStringSlicePointer(p, cmd, aclFlag) - if acls == nil { - return nil, &cliErr.EmptyUpdateError{} - } - model := inputModel{ - GlobalFlagModel: globalFlags, - InstanceId: instanceId, - Acls: acls, + GlobalFlagModel: globalFlags, + InstanceId: instanceId, + Acls: acls, + KmsKeyId: flags.FlagToStringPointer(p, cmd, kmsKeyIdFlag), + KmsKeyringId: flags.FlagToStringPointer(p, cmd, kmsKeyringIdFlag), + KmsKeyVersion: flags.FlagToInt64Pointer(p, cmd, kmsKeyVersionFlag), + KmsServiceAccountEmail: flags.FlagToStringPointer(p, cmd, kmsServiceAccountEmailFlag), } p.DebugInputModel(model) return &model, nil } -func buildRequest(ctx context.Context, model *inputModel, apiClient *secretsmanager.APIClient) secretsmanager.ApiUpdateACLsRequest { +func buildRequest(ctx context.Context, model *inputModel, instanceName string, apiClient *secretsmanager.APIClient) interface{ Execute() error } { + if model.KmsKeyId != nil { + return buildUpdateInstanceRequest(ctx, model, instanceName, apiClient) + } + + return buildUpdateACLsRequest(ctx, model, apiClient) +} + +func buildUpdateInstanceRequest(ctx context.Context, model *inputModel, instanceName string, apiClient *secretsmanager.APIClient) secretsmanager.ApiUpdateInstanceRequest { + req := apiClient.UpdateInstance(ctx, model.ProjectId, model.InstanceId) + + payload := secretsmanager.UpdateInstancePayload{ + Name: &instanceName, + KmsKey: &secretsmanager.KmsKeyPayload{ + KeyId: model.KmsKeyId, + KeyRingId: model.KmsKeyringId, + KeyVersion: model.KmsKeyVersion, + ServiceAccountEmail: model.KmsServiceAccountEmail, + }, + } + + req = req.UpdateInstancePayload(payload) + + return req +} + +func buildUpdateACLsRequest(ctx context.Context, model *inputModel, apiClient *secretsmanager.APIClient) secretsmanager.ApiUpdateACLsRequest { req := apiClient.UpdateACLs(ctx, model.ProjectId, model.InstanceId) cidrs := []secretsmanager.UpdateACLPayload{} diff --git a/internal/cmd/secrets-manager/instance/update/update_test.go b/internal/cmd/secrets-manager/instance/update/update_test.go index 24e14d1fb..d8c77b942 100644 --- a/internal/cmd/secrets-manager/instance/update/update_test.go +++ b/internal/cmd/secrets-manager/instance/update/update_test.go @@ -4,10 +4,8 @@ import ( "context" "testing" - "github.com/stackitcloud/stackit-cli/internal/pkg/types" - "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" - "github.com/stackitcloud/stackit-cli/internal/pkg/print" + "github.com/stackitcloud/stackit-cli/internal/pkg/testutils" "github.com/stackitcloud/stackit-cli/internal/pkg/utils" "github.com/google/go-cmp/cmp" @@ -33,6 +31,14 @@ var ( testInstanceId = uuid.NewString() ) +const ( + testInstanceName = "test-instance" + testKmsKeyId = "key-id" + testKmsKeyringId = "keyring-id" + testKmsKeyVersion = int64(1) + testKmsServiceAccountEmail = "my-service-account-1234567@sa.stackit.cloud" +) + func fixtureArgValues(mods ...func(argValues []string)) []string { argValues := []string{ testInstanceId, @@ -82,6 +88,24 @@ func fixtureRequest(mods ...func(request *secretsmanager.ApiUpdateACLsRequest)) return request } +func fixtureUpdateInstanceRequest(mods ...func(request *secretsmanager.ApiUpdateInstanceRequest)) secretsmanager.ApiUpdateInstanceRequest { + request := testClient.UpdateInstance(testCtx, testProjectId, testInstanceId) + request = request.UpdateInstancePayload(secretsmanager.UpdateInstancePayload{ + Name: utils.Ptr(testInstanceName), + KmsKey: &secretsmanager.KmsKeyPayload{ + KeyId: utils.Ptr(testKmsKeyId), + KeyRingId: utils.Ptr(testKmsKeyringId), + KeyVersion: utils.Ptr(testKmsKeyVersion), + ServiceAccountEmail: utils.Ptr(testKmsServiceAccountEmail), + }, + }) + + for _, mod := range mods { + mod(&request) + } + return request +} + func TestParseInput(t *testing.T) { tests := []struct { description string @@ -111,13 +135,7 @@ func TestParseInput(t *testing.T) { isValid: false, }, { - description: "no flag values", - argValues: fixtureArgValues(), - flagValues: map[string]string{}, - isValid: false, - }, - { - description: "required flags only (no values to update)", + description: "no update flags", argValues: fixtureArgValues(), flagValues: map[string]string{ projectIdFlag: testProjectId, @@ -172,6 +190,28 @@ func TestParseInput(t *testing.T) { flagValues: fixtureFlagValues(), isValid: false, }, + { + description: "kms key id without other required kms flags", + argValues: fixtureArgValues(), + flagValues: map[string]string{ + projectIdFlag: testProjectId, + kmsKeyIdFlag: "key-id", + }, + isValid: false, + }, + { + description: "acl flag conflicts with kms flags", + argValues: fixtureArgValues(), + flagValues: map[string]string{ + projectIdFlag: testProjectId, + aclFlag: testACL1, + kmsKeyIdFlag: "key-id", + kmsKeyringIdFlag: "keyring-id", + kmsKeyVersionFlag: "1", + kmsServiceAccountEmailFlag: "my-service-account-1234567@sa.stackit.cloud", + }, + isValid: false, + }, { description: "repeated acl flags", argValues: fixtureArgValues(), @@ -195,68 +235,32 @@ func TestParseInput(t *testing.T) { ) }), }, + { + description: "kms flags", + argValues: fixtureArgValues(), + flagValues: map[string]string{ + projectIdFlag: testProjectId, + kmsKeyIdFlag: testKmsKeyId, + kmsKeyringIdFlag: testKmsKeyringId, + kmsKeyVersionFlag: "1", + kmsServiceAccountEmailFlag: testKmsServiceAccountEmail, + }, + isValid: true, + expectedModel: fixtureInputModel(func(model *inputModel) { + model.Acls = nil + model.KmsKeyId = utils.Ptr(testKmsKeyId) + model.KmsKeyringId = utils.Ptr(testKmsKeyringId) + model.KmsKeyVersion = utils.Ptr(testKmsKeyVersion) + model.KmsServiceAccountEmail = utils.Ptr(testKmsServiceAccountEmail) + }), + }, } for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { - p := print.NewPrinter() - cmd := NewCmd(&types.CmdParams{Printer: p}) - err := globalflags.Configure(cmd.Flags()) - if err != nil { - t.Fatalf("configure global flags: %v", err) - } - - for flag, value := range tt.flagValues { - err := cmd.Flags().Set(flag, value) - if err != nil { - if !tt.isValid { - return - } - t.Fatalf("setting flag --%s=%s: %v", flag, value, err) - } - } - - for _, value := range tt.aclValues { - err := cmd.Flags().Set(aclFlag, value) - if err != nil { - if !tt.isValid { - return - } - t.Fatalf("setting flag --%s=%s: %v", aclFlag, value, err) - } - } - - err = cmd.ValidateArgs(tt.argValues) - if err != nil { - if !tt.isValid { - return - } - t.Fatalf("error validating args: %v", err) - } - - err = cmd.ValidateRequiredFlags() - if err != nil { - if !tt.isValid { - return - } - t.Fatalf("error validating flags: %v", err) - } - - model, err := parseInput(p, cmd, tt.argValues) - if err != nil { - if !tt.isValid { - return - } - t.Fatalf("error parsing flags: %v", err) - } - - if !tt.isValid { - t.Fatalf("did not fail on invalid input") - } - diff := cmp.Diff(model, tt.expectedModel) - if diff != "" { - t.Fatalf("Data does not match: %s", diff) - } + testutils.TestParseInputWithAdditionalFlags(t, NewCmd, parseInput, tt.expectedModel, tt.argValues, tt.flagValues, map[string][]string{ + aclFlag: tt.aclValues, + }, tt.isValid) }) } } @@ -286,9 +290,13 @@ func TestBuildRequest(t *testing.T) { for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { - request := buildRequest(testCtx, tt.model, testClient) + request := buildRequest(testCtx, tt.model, testInstanceName, testClient) + aclRequest, ok := request.(secretsmanager.ApiUpdateACLsRequest) + if !ok { + t.Fatalf("expected ACL update request, got %T", request) + } - diff := cmp.Diff(request, tt.expectedRequest, + diff := cmp.Diff(aclRequest, tt.expectedRequest, cmp.AllowUnexported(tt.expectedRequest), cmpopts.EquateComparable(testCtx), ) @@ -298,3 +306,28 @@ func TestBuildRequest(t *testing.T) { }) } } + +func TestBuildRequestKms(t *testing.T) { + model := fixtureInputModel(func(model *inputModel) { + model.Acls = nil + model.KmsKeyId = utils.Ptr(testKmsKeyId) + model.KmsKeyringId = utils.Ptr(testKmsKeyringId) + model.KmsKeyVersion = utils.Ptr(testKmsKeyVersion) + model.KmsServiceAccountEmail = utils.Ptr(testKmsServiceAccountEmail) + }) + + request := buildRequest(testCtx, model, testInstanceName, testClient) + updateRequest, ok := request.(secretsmanager.ApiUpdateInstanceRequest) + if !ok { + t.Fatalf("expected instance update request, got %T", request) + } + + expectedRequest := fixtureUpdateInstanceRequest() + diff := cmp.Diff(updateRequest, expectedRequest, + cmp.AllowUnexported(expectedRequest), + cmpopts.EquateComparable(testCtx), + ) + if diff != "" { + t.Fatalf("Data does not match: %s", diff) + } +}