diff --git a/.go-version b/.go-version index 7a429d68a3..8407e26008 100644 --- a/.go-version +++ b/.go-version @@ -1 +1 @@ -1.24.6 +1.24.7 diff --git a/go.mod b/go.mod index dc0e179098..1e9216ed7f 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/confluentinc/cli/v4 -go 1.24.6 +go 1.24.7 require ( github.com/antihax/optional v1.0.0 @@ -18,7 +18,7 @@ require ( github.com/confluentinc/ccloud-sdk-go-v2/ai v0.1.0 github.com/confluentinc/ccloud-sdk-go-v2/apikeys v0.4.0 github.com/confluentinc/ccloud-sdk-go-v2/billing v0.3.0 - github.com/confluentinc/ccloud-sdk-go-v2/byok v0.0.2 + github.com/confluentinc/ccloud-sdk-go-v2/byok v0.0.9 github.com/confluentinc/ccloud-sdk-go-v2/cam v0.3.0 github.com/confluentinc/ccloud-sdk-go-v2/ccl v0.4.0 github.com/confluentinc/ccloud-sdk-go-v2/ccpm v0.0.1 diff --git a/go.sum b/go.sum index d6b9f27d60..552a434fc0 100644 --- a/go.sum +++ b/go.sum @@ -194,8 +194,8 @@ github.com/confluentinc/ccloud-sdk-go-v2/apikeys v0.4.0 h1:8fWyLwMuy8ec0MVF5Avd5 github.com/confluentinc/ccloud-sdk-go-v2/apikeys v0.4.0/go.mod h1:wNa9Qg2e2v/+PQsUyKh+qB22hhLkPR6Ahy6rP+1jmGI= github.com/confluentinc/ccloud-sdk-go-v2/billing v0.3.0 h1:a2EaPzwLEYkgil7rlsqRUlt994PMGubtdgRrF8Kbo10= github.com/confluentinc/ccloud-sdk-go-v2/billing v0.3.0/go.mod h1:c7nUjQ5pQCqz4LagF1qatcj5NX4icoiSTaCxfdxAwsY= -github.com/confluentinc/ccloud-sdk-go-v2/byok v0.0.2 h1:BV/dPTFVovJPylrcr9lcSmukCVxBxyUeHBr6hp7zUNk= -github.com/confluentinc/ccloud-sdk-go-v2/byok v0.0.2/go.mod h1:MMtRTfg1g32bQrRwfqvGpe+grS5pQzeq9V+L5GKydV4= +github.com/confluentinc/ccloud-sdk-go-v2/byok v0.0.9 h1:TFz/gJ0tPnTsEE56xJwLtU5ykTpfPv0vZwI1jS1QUMg= +github.com/confluentinc/ccloud-sdk-go-v2/byok v0.0.9/go.mod h1:evP8lAu09jGJMQX54bUaJxmT17eQcN4GsmzjTAZst6w= github.com/confluentinc/ccloud-sdk-go-v2/cam v0.3.0 h1:9MMm9VeJ8ZVg9A6ofplPPvLZH4OGP56PtrJ/WP18EtY= github.com/confluentinc/ccloud-sdk-go-v2/cam v0.3.0/go.mod h1:vderFceIQXBEdhkulkwTZ0SPxHz4yZ3uDMne/FA4dJ8= github.com/confluentinc/ccloud-sdk-go-v2/ccl v0.4.0 h1:dUFB7PM/eQbI/AhRHyMh4Pd7xsDDlhonE3/+kwvXVnY= diff --git a/internal/byok/command.go b/internal/byok/command.go index db42dbd96a..4df4f7fa99 100644 --- a/internal/byok/command.go +++ b/internal/byok/command.go @@ -13,12 +13,17 @@ type command struct { } type out struct { - Id string `human:"ID" serialized:"id"` - Key string `human:"Key" serialized:"key"` - Roles []string `human:"Roles" serialized:"roles"` - Cloud string `human:"Cloud" serialized:"cloud"` - State string `human:"State" serialized:"state"` - CreatedAt string `human:"Created At" serialized:"created_at"` + Id string `human:"ID" serialized:"id"` + DisplayName string `human:"Display Name,omitempty" serialized:"display_name,omitempty"` + Key string `human:"Key" serialized:"key"` + Roles []string `human:"Roles" serialized:"roles"` + Cloud string `human:"Cloud" serialized:"cloud"` + ValidationRegion string `human:"Region,omitempty" serialized:"region,omitempty"` + State string `human:"State" serialized:"state"` + CreatedAt string `human:"Created At" serialized:"created_at"` + ValidationPhase string `human:"Validation Phase" serialized:"validation_phase"` + ValidationSince string `human:"Validation Since" serialized:"validation_since"` + ValidationMessage string `human:"Message,omitempty" serialized:"message,omitempty"` } func New(prerunner pcmd.PreRunner) *cobra.Command { @@ -34,6 +39,7 @@ func New(prerunner pcmd.PreRunner) *cobra.Command { cmd.AddCommand(c.newDeleteCommand()) cmd.AddCommand(c.newDescribeCommand()) cmd.AddCommand(c.newListCommand()) + cmd.AddCommand(c.newUpdateCommand()) return cmd } diff --git a/internal/byok/command_create.go b/internal/byok/command_create.go index 190f6cb801..0811eeb6e9 100644 --- a/internal/byok/command_create.go +++ b/internal/byok/command_create.go @@ -74,6 +74,7 @@ func (c *command) newCreateCommand() *cobra.Command { cmd.Flags().String("key-vault", "", "The ID of the Azure Key Vault where the key is stored.") cmd.Flags().String("tenant", "", "The ID of the Azure Active Directory tenant that the key vault belongs to.") + cmd.Flags().String("display-name", "", "A human-readable name for the self-managed key.") pcmd.AddOutputFlag(cmd) cmd.MarkFlagsRequiredTogether("key-vault", "tenant") @@ -81,14 +82,18 @@ func (c *command) newCreateCommand() *cobra.Command { return cmd } -func (c *command) createAwsKeyRequest(keyArn string) byokv1.ByokV1Key { - return byokv1.ByokV1Key{Key: &byokv1.ByokV1KeyKeyOneOf{ByokV1AwsKey: &byokv1.ByokV1AwsKey{ +func (c *command) createAwsKeyRequest(keyArn, displayName string) byokv1.ByokV1Key { + key := byokv1.ByokV1Key{Key: &byokv1.ByokV1KeyKeyOneOf{ByokV1AwsKey: &byokv1.ByokV1AwsKey{ KeyArn: keyArn, Kind: "AwsKey", }}} + if displayName != "" { + key.SetDisplayName(displayName) + } + return key } -func (c *command) createAzureKeyRequest(cmd *cobra.Command, keyString string) (byokv1.ByokV1Key, error) { +func (c *command) createAzureKeyRequest(cmd *cobra.Command, keyString, displayName string) (byokv1.ByokV1Key, error) { keyVault, err := cmd.Flags().GetString("key-vault") if err != nil { return byokv1.ByokV1Key{}, err @@ -106,33 +111,46 @@ func (c *command) createAzureKeyRequest(cmd *cobra.Command, keyString string) (b Kind: "AzureKey", }}} + if displayName != "" { + keyReq.SetDisplayName(displayName) + } + return keyReq, nil } -func (c *command) createGcpKeyRequest(keyString string) byokv1.ByokV1Key { - return byokv1.ByokV1Key{Key: &byokv1.ByokV1KeyKeyOneOf{ByokV1GcpKey: &byokv1.ByokV1GcpKey{ +func (c *command) createGcpKeyRequest(keyString, displayName string) byokv1.ByokV1Key { + key := byokv1.ByokV1Key{Key: &byokv1.ByokV1KeyKeyOneOf{ByokV1GcpKey: &byokv1.ByokV1GcpKey{ KeyId: keyString, Kind: "GcpKey", }}} + if displayName != "" { + key.SetDisplayName(displayName) + } + return key } func (c *command) create(cmd *cobra.Command, args []string) error { keyString := args[0] var keyReq byokv1.ByokV1Key + displayName, err := cmd.Flags().GetString("display-name") + if err != nil { + return err + } + switch { case cmd.Flags().Changed("key-vault") && cmd.Flags().Changed("tenant"): keyString = removeKeyVersionFromAzureKeyId(keyString) - request, err := c.createAzureKeyRequest(cmd, keyString) + request, err := c.createAzureKeyRequest(cmd, keyString, displayName) if err != nil { return err } keyReq = request case isAWSKey(keyString): - keyReq = c.createAwsKeyRequest(keyString) + keyReq = c.createAwsKeyRequest(keyString, displayName) case isGcpKey(keyString): - keyReq = c.createGcpKeyRequest(keyString) + keyReq = c.createGcpKeyRequest(keyString, displayName) default: return fmt.Errorf("invalid key format: %s", keyString) } diff --git a/internal/byok/command_describe.go b/internal/byok/command_describe.go index 8221002de6..de5beb093d 100644 --- a/internal/byok/command_describe.go +++ b/internal/byok/command_describe.go @@ -53,12 +53,17 @@ func (c *command) outputByokKeyDescription(cmd *cobra.Command, key byokv1.ByokV1 table := output.NewTable(cmd) table.Add(&out{ - Id: key.GetId(), - Key: keyString, - Roles: roles, - Cloud: key.GetProvider(), - State: key.GetState(), - CreatedAt: key.Metadata.CreatedAt.String(), + Id: key.GetId(), + DisplayName: key.GetDisplayName(), + Key: keyString, + Roles: roles, + Cloud: key.GetProvider(), + ValidationRegion: key.Validation.GetRegion(), + State: key.GetState(), + CreatedAt: key.Metadata.CreatedAt.String(), + ValidationPhase: key.Validation.GetPhase(), + ValidationMessage: key.Validation.GetMessage(), + ValidationSince: key.Validation.GetSince().String(), }) table.Print() diff --git a/internal/byok/command_list.go b/internal/byok/command_list.go index b3d077b935..8e6bce3b13 100644 --- a/internal/byok/command_list.go +++ b/internal/byok/command_list.go @@ -19,6 +19,10 @@ func (c *command) newListCommand() *cobra.Command { pcmd.AddCloudFlag(cmd) pcmd.AddByokStateFlag(cmd) + cmd.Flags().String("region", "", "Filter by region.") + pcmd.AddByokValidationPhaseFlag(cmd) + cmd.Flags().String("display-name", "", "Filter by display name.") + cmd.Flags().String("key", "", "Filter by key identifier.") pcmd.AddOutputFlag(cmd) return cmd @@ -49,7 +53,27 @@ func (c *command) list(cmd *cobra.Command, _ []string) error { state = "AVAILABLE" } - keys, err := c.V2Client.ListByokKeys(cloud, state) + region, err := cmd.Flags().GetString("region") + if err != nil { + return err + } + + phase, err := cmd.Flags().GetString("validation-phase") + if err != nil { + return err + } + + displayName, err := cmd.Flags().GetString("display-name") + if err != nil { + return err + } + + key, err := cmd.Flags().GetString("key") + if err != nil { + return err + } + + keys, err := c.V2Client.ListByokKeys(cloud, state, region, phase, displayName, key) if err != nil { return err } @@ -69,17 +93,19 @@ func (c *command) list(cmd *cobra.Command, _ []string) error { } list.Add(&out{ - Id: key.GetId(), - Key: keyString, - Cloud: key.GetProvider(), - State: key.GetState(), - CreatedAt: key.Metadata.CreatedAt.String(), + Id: key.GetId(), + DisplayName: key.GetDisplayName(), + Key: keyString, + Cloud: key.GetProvider(), + State: key.GetState(), + CreatedAt: key.Metadata.CreatedAt.String(), + ValidationPhase: key.Validation.GetPhase(), }) } // The API returns a list sorted by creation date already list.Sort(false) - list.Filter([]string{"Id", "Key", "Cloud", "State", "CreatedAt"}) + list.Filter([]string{"Id", "DisplayName", "Key", "Cloud", "State", "ValidationPhase", "CreatedAt"}) return list.Print() } diff --git a/internal/byok/command_update.go b/internal/byok/command_update.go new file mode 100644 index 0000000000..f4e9cf73a7 --- /dev/null +++ b/internal/byok/command_update.go @@ -0,0 +1,56 @@ +package byok + +import ( + "github.com/spf13/cobra" + + byokv1 "github.com/confluentinc/ccloud-sdk-go-v2/byok/v1" + + pcmd "github.com/confluentinc/cli/v4/pkg/cmd" + "github.com/confluentinc/cli/v4/pkg/errors" + "github.com/confluentinc/cli/v4/pkg/examples" +) + +func (c *command) newUpdateCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "update ", + Short: "Update a self-managed key.", + Long: "Update a self-managed key in Confluent Cloud.", + Args: cobra.ExactArgs(1), + ValidArgsFunction: pcmd.NewValidArgsFunction(c.validArgs), + RunE: c.update, + Example: examples.BuildExampleString( + examples.Example{ + Text: `Update the display name of self-managed key "cck-12345".`, + Code: `confluent byok update cck-12345 --display-name "My production key"`, + }, + ), + } + + cmd.Flags().String("display-name", "", "A human-readable name for the self-managed key.") + pcmd.AddOutputFlag(cmd) + + cobra.CheckErr(cmd.MarkFlagRequired("display-name")) + + return cmd +} + +func (c *command) update(cmd *cobra.Command, args []string) error { + keyId := args[0] + + displayName, err := cmd.Flags().GetString("display-name") + if err != nil { + return err + } + + // Use dedicated update struct following the pattern from API Keys + updateReq := byokv1.ByokV1KeyUpdate{ + DisplayName: byokv1.PtrString(displayName), + } + + key, httpResp, err := c.V2Client.UpdateByokKey(keyId, updateReq) + if err != nil { + return errors.CatchByokKeyNotFoundError(err, httpResp) + } + + return c.outputByokKeyDescription(cmd, key) +} diff --git a/pkg/ccloudv2/byok.go b/pkg/ccloudv2/byok.go index ecb83976ea..356d000220 100644 --- a/pkg/ccloudv2/byok.go +++ b/pkg/ccloudv2/byok.go @@ -31,17 +31,21 @@ func (c *Client) GetByokKey(keyId string) (byokv1.ByokV1Key, *http.Response, err return c.ByokClient.KeysByokV1Api.GetByokV1Key(c.byokApiContext(), keyId).Execute() } +func (c *Client) UpdateByokKey(keyId string, keyUpdate byokv1.ByokV1KeyUpdate) (byokv1.ByokV1Key, *http.Response, error) { + return c.ByokClient.KeysByokV1Api.UpdateByokV1Key(c.byokApiContext(), keyId).ByokV1KeyUpdate(keyUpdate).Execute() +} + func (c *Client) DeleteByokKey(keyId string) (*http.Response, error) { return c.ByokClient.KeysByokV1Api.DeleteByokV1Key(c.byokApiContext(), keyId).Execute() } -func (c *Client) ListByokKeys(provider, state string) ([]byokv1.ByokV1Key, error) { +func (c *Client) ListByokKeys(provider, state, region, phase, displayName, key string) ([]byokv1.ByokV1Key, error) { var list []byokv1.ByokV1Key done := false pageToken := "" for !done { - page, httpResp, err := c.executeListByokKeys(pageToken, provider, state) + page, httpResp, err := c.executeListByokKeys(pageToken, provider, state, region, phase, displayName, key) if err != nil { return nil, errors.CatchCCloudV2Error(err, httpResp) } @@ -55,7 +59,7 @@ func (c *Client) ListByokKeys(provider, state string) ([]byokv1.ByokV1Key, error return list, nil } -func (c *Client) executeListByokKeys(pageToken, provider, state string) (byokv1.ByokV1KeyList, *http.Response, error) { +func (c *Client) executeListByokKeys(pageToken, provider, state, region, phase, displayName, key string) (byokv1.ByokV1KeyList, *http.Response, error) { req := c.ByokClient.KeysByokV1Api.ListByokV1Keys(c.byokApiContext()).PageSize(ccloudV2ListPageSize) if provider != "" { req = req.Provider(provider) @@ -63,6 +67,18 @@ func (c *Client) executeListByokKeys(pageToken, provider, state string) (byokv1. if state != "" { req = req.State(state) } + if region != "" { + req = req.ValidationRegion(region) + } + if phase != "" { + req = req.ValidationPhase(phase) + } + if displayName != "" { + req = req.DisplayName(displayName) + } + if key != "" { + req = req.Key(key) + } if pageToken != "" { req = req.PageToken(pageToken) } diff --git a/pkg/cmd/flags.go b/pkg/cmd/flags.go index 6bbfbb0dcd..e6456bea8e 100644 --- a/pkg/cmd/flags.go +++ b/pkg/cmd/flags.go @@ -67,7 +67,7 @@ func AddByokKeyFlag(cmd *cobra.Command, command *AuthenticatedCLICommand) { } func AutocompleteByokKeyIds(client *ccloudv2.Client) []string { - keys, err := client.ListByokKeys("", "") + keys, err := client.ListByokKeys("", "", "", "", "", "") if err != nil { return nil } @@ -84,6 +84,11 @@ func AddByokStateFlag(cmd *cobra.Command) { RegisterFlagCompletionFunc(cmd, "state", func(_ *cobra.Command, _ []string) []string { return []string{"in-use", "available"} }) } +func AddByokValidationPhaseFlag(cmd *cobra.Command) { + cmd.Flags().String("validation-phase", "", fmt.Sprintf("Specify the validation phase as %s.", utils.ArrayToCommaDelimitedString([]string{"valid", "invalid", "initializing"}, "or"))) + RegisterFlagCompletionFunc(cmd, "validation-phase", func(_ *cobra.Command, _ []string) []string { return []string{"valid", "invalid", "initializing"} }) +} + func AddCloudFlag(cmd *cobra.Command) { cmd.Flags().String("cloud", "", fmt.Sprintf("Specify the cloud provider as %s.", utils.ArrayToCommaDelimitedString(kafka.Clouds, "or"))) RegisterFlagCompletionFunc(cmd, "cloud", func(_ *cobra.Command, _ []string) []string { return kafka.Clouds }) diff --git a/test/byok_test.go b/test/byok_test.go index b0e1a0d358..8ee31c8ed0 100644 --- a/test/byok_test.go +++ b/test/byok_test.go @@ -9,12 +9,17 @@ func (s *CLITestSuite) TestByok() { {args: "byok list --state in-use", fixture: "byok/list_2.golden"}, {args: "byok list --cloud aws", fixture: "byok/list_3.golden"}, {args: "byok list --state in-use --cloud azure", fixture: "byok/list_4.golden"}, + {args: "byok list --region us-east-1", fixture: "byok/list_5.golden"}, + {args: "byok list --validation-phase VALID", fixture: "byok/list_6.golden"}, + {args: "byok list --display-name 'Development AWS Key'", fixture: "byok/list_7.golden"}, + {args: "byok list --key 'a-vault'", fixture: "byok/list_8.golden"}, // create tests {args: "byok create arn:aws:kms:us-west-2:037803949979:key/0e2609e3-a0bf-4f39-aedf-8b1f63b16d81", fixture: "byok/create_1.golden"}, {args: "byok create https://a-vault.vault.azure.net/keys/a-key/00000000000000000000000000000000 --tenant 00000000-0000-0000-0000-000000000000 --key-vault /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/a-resourcegroups/providers/Microsoft.KeyVault/vaults/a-vault", fixture: "byok/create_2.golden"}, {args: "byok create https://a-vault.vault.azure.net/keys/a-key/00000000000000000000000000000000 --tenant 00000000-0000-0000-0000-000000000000", fixture: "byok/create_3.golden", exitCode: 1}, {args: "byok create https://a-vault.vault.azure.net/keys/a-key/00000000000000000000000000000000", fixture: "byok/create_4.golden", exitCode: 1}, {args: "byok create projects/exampleproject/locations/us-central1/keyRings/testkeyring/cryptoKeys/testbyokkey/cryptoKeyVersions/3", fixture: "byok/create_5.golden"}, + {args: "byok create projects/exampleproject/locations/us-central1/keyRings/testkeyring/cryptoKeys/testbyokkey/cryptoKeyVersions/4 --display-name 'Test GCP Key'", fixture: "byok/create_6.golden"}, } resetConfiguration(s.T(), false) @@ -58,6 +63,19 @@ func (s *CLITestSuite) TestByokDescribe() { } } +func (s *CLITestSuite) TestByokUpdate() { + tests := []CLITest{ + {args: `byok update cck-001 --display-name "Updated Production Key"`, fixture: "byok/update-success.golden"}, + {args: `byok update cck-001 --display-name "Updated Production Key" -o json`, fixture: "byok/update-success-json.golden"}, + {args: `byok update cck-does-not-exist --display-name "Updated Production Key"`, fixture: "byok/update-fail.golden", exitCode: 1}, + } + + for _, test := range tests { + test.login = "cloud" + s.runIntegrationTest(test) + } +} + func (s *CLITestSuite) TestByok_Autocomplete() { test := CLITest{args: `__complete byok describe ""`, login: "cloud", fixture: "byok/describe-autocomplete.golden"} s.runIntegrationTest(test) diff --git a/test/fixtures/output/byok/create-help.golden b/test/fixtures/output/byok/create-help.golden index 9fa0035997..35263b14ad 100644 --- a/test/fixtures/output/byok/create-help.golden +++ b/test/fixtures/output/byok/create-help.golden @@ -17,9 +17,10 @@ Register a new self-managed encryption key for GCP: $ confluent byok create "projects/exampleproject/locations/us-central1/keyRings/testkeyring/cryptoKeys/testbyokkey/cryptoKeyVersions/3" Flags: - --key-vault string The ID of the Azure Key Vault where the key is stored. - --tenant string The ID of the Azure Active Directory tenant that the key vault belongs to. - -o, --output string Specify the output format as "human", "json", or "yaml". (default "human") + --key-vault string The ID of the Azure Key Vault where the key is stored. + --tenant string The ID of the Azure Active Directory tenant that the key vault belongs to. + --display-name string A human-readable name for the self-managed key. + -o, --output string Specify the output format as "human", "json", or "yaml". (default "human") Global Flags: -h, --help Show help for this command. diff --git a/test/fixtures/output/byok/create_1.golden b/test/fixtures/output/byok/create_1.golden index ce06ef44c2..272eca8250 100644 --- a/test/fixtures/output/byok/create_1.golden +++ b/test/fixtures/output/byok/create_1.golden @@ -1,12 +1,14 @@ -+------------+-----------------------------------------------------------------------------+ -| ID | cck-004 | -| Key | arn:aws:kms:us-west-2:037803949979:key/0e2609e3-a0bf-4f39-aedf-8b1f63b16d81 | -| Roles | arn:aws:iam::123456789012:role/role1, | -| | arn:aws:iam::123456789012:role/role2 | -| Cloud | AWS | -| State | AVAILABLE | -| Created At | 2022-12-24 00:00:00 +0000 UTC | -+------------+-----------------------------------------------------------------------------+ ++------------------+-----------------------------------------------------------------------------+ +| ID | cck-004 | +| Key | arn:aws:kms:us-west-2:037803949979:key/0e2609e3-a0bf-4f39-aedf-8b1f63b16d81 | +| Roles | arn:aws:iam::123456789012:role/role1, | +| | arn:aws:iam::123456789012:role/role2 | +| Cloud | AWS | +| State | AVAILABLE | +| Created At | 2022-12-24 00:00:00 +0000 UTC | +| Validation Phase | INITIALIZING | +| Validation Since | 2022-12-24 00:00:00 +0000 UTC | ++------------------+-----------------------------------------------------------------------------+ Copy and append these permissions into the key policy "Statements" field of the ARN in your AWS key management system to authorize access for your Confluent Cloud cluster. diff --git a/test/fixtures/output/byok/create_2.golden b/test/fixtures/output/byok/create_2.golden index f41bad6c1f..825bf3e038 100644 --- a/test/fixtures/output/byok/create_2.golden +++ b/test/fixtures/output/byok/create_2.golden @@ -1,11 +1,13 @@ -+------------+--------------------------------------------+ -| ID | cck-004 | -| Key | https://a-vault.vault.azure.net/keys/a-key | -| Roles | 12345678-1234-1234-1234-123456789012 | -| Cloud | AZURE | -| State | AVAILABLE | -| Created At | 2022-12-24 00:00:00 +0000 UTC | -+------------+--------------------------------------------+ ++------------------+--------------------------------------------+ +| ID | cck-004 | +| Key | https://a-vault.vault.azure.net/keys/a-key | +| Roles | 12345678-1234-1234-1234-123456789012 | +| Cloud | AZURE | +| State | AVAILABLE | +| Created At | 2022-12-24 00:00:00 +0000 UTC | +| Validation Phase | INITIALIZING | +| Validation Since | 2022-12-24 00:00:00 +0000 UTC | ++------------------+--------------------------------------------+ To ensure the key vault has the correct role assignments, please run the following Azure CLI command (certified for `az` v2.45): diff --git a/test/fixtures/output/byok/create_3.golden b/test/fixtures/output/byok/create_3.golden index b1294b5f3a..52b60c1978 100644 --- a/test/fixtures/output/byok/create_3.golden +++ b/test/fixtures/output/byok/create_3.golden @@ -16,9 +16,10 @@ Register a new self-managed encryption key for GCP: $ confluent byok create "projects/exampleproject/locations/us-central1/keyRings/testkeyring/cryptoKeys/testbyokkey/cryptoKeyVersions/3" Flags: - --key-vault string The ID of the Azure Key Vault where the key is stored. - --tenant string The ID of the Azure Active Directory tenant that the key vault belongs to. - -o, --output string Specify the output format as "human", "json", or "yaml". (default "human") + --key-vault string The ID of the Azure Key Vault where the key is stored. + --tenant string The ID of the Azure Active Directory tenant that the key vault belongs to. + --display-name string A human-readable name for the self-managed key. + -o, --output string Specify the output format as "human", "json", or "yaml". (default "human") Global Flags: -h, --help Show help for this command. diff --git a/test/fixtures/output/byok/create_5.golden b/test/fixtures/output/byok/create_5.golden index 217f5386e4..27574a8cbf 100644 --- a/test/fixtures/output/byok/create_5.golden +++ b/test/fixtures/output/byok/create_5.golden @@ -1,11 +1,13 @@ -+------------+---------------------------------------------------------------------------------------------------------------+ -| ID | cck-004 | -| Key | projects/exampleproject/locations/us-central1/keyRings/testkeyring/cryptoKeys/testbyokkey/cryptoKeyVersions/3 | -| Roles | | -| Cloud | GCP | -| State | AVAILABLE | -| Created At | 2022-12-24 00:00:00 +0000 UTC | -+------------+---------------------------------------------------------------------------------------------------------------+ ++------------------+---------------------------------------------------------------------------------------------------------------+ +| ID | cck-004 | +| Key | projects/exampleproject/locations/us-central1/keyRings/testkeyring/cryptoKeys/testbyokkey/cryptoKeyVersions/3 | +| Roles | | +| Cloud | GCP | +| State | AVAILABLE | +| Created At | 2022-12-24 00:00:00 +0000 UTC | +| Validation Phase | INITIALIZING | +| Validation Since | 2022-12-24 00:00:00 +0000 UTC | ++------------------+---------------------------------------------------------------------------------------------------------------+ To ensure the key has the correct role assignments, please run the following Google Cloud CLI command: diff --git a/test/fixtures/output/byok/create_6.golden b/test/fixtures/output/byok/create_6.golden new file mode 100644 index 0000000000..ad3d82f0fb --- /dev/null +++ b/test/fixtures/output/byok/create_6.golden @@ -0,0 +1,25 @@ ++------------------+---------------------------------------------------------------------------------------------------------------+ +| ID | cck-004 | +| Display Name | Test GCP Key | +| Key | projects/exampleproject/locations/us-central1/keyRings/testkeyring/cryptoKeys/testbyokkey/cryptoKeyVersions/4 | +| Roles | | +| Cloud | GCP | +| State | AVAILABLE | +| Created At | 2022-12-24 00:00:00 +0000 UTC | +| Validation Phase | INITIALIZING | +| Validation Since | 2022-12-24 00:00:00 +0000 UTC | ++------------------+---------------------------------------------------------------------------------------------------------------+ + +To ensure the key has the correct role assignments, please run the following Google Cloud CLI command: + + +gcloud iam roles create testkeyring_testbyokkey_custom_kms_role \ + --project=exampleproject \ + --description="Grant necessary permissions for Confluent to access KMS key" \ + --permissions=cloudkms.cryptoKeyVersions.useToDecrypt,cloudkms.cryptoKeyVersions.useToEncrypt,cloudkms.cryptoKeys.get && \ +gcloud kms keys add-iam-policy-binding testbyokkey \ + --project=exampleproject \ + --keyring="testkeyring" \ + --location="us-central1" \ + --member="group:" \ + --role="projects/exampleproject/roles/testkeyring_testbyokkey_custom_kms_role" diff --git a/test/fixtures/output/byok/describe-aws-json.golden b/test/fixtures/output/byok/describe-aws-json.golden index fef5ec5035..a1a1b2b0f7 100644 --- a/test/fixtures/output/byok/describe-aws-json.golden +++ b/test/fixtures/output/byok/describe-aws-json.golden @@ -1,11 +1,15 @@ { "id": "cck-001", + "display_name": "Production AWS Key", "key": "arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012", "roles": [ "arn:aws:iam::123456789012:role/role1", "arn:aws:iam::123456789012:role/role2" ], "cloud": "AWS", + "region": "us-east-1", "state": "IN_USE", - "created_at": "2022-11-12 08:24:00 +0000 UTC" + "created_at": "2022-11-12 08:24:00 +0000 UTC", + "validation_phase": "VALID", + "validation_since": "2022-11-12 08:30:00 +0000 UTC" } diff --git a/test/fixtures/output/byok/describe-aws.golden b/test/fixtures/output/byok/describe-aws.golden index c99faae73f..d36b8a61c1 100644 --- a/test/fixtures/output/byok/describe-aws.golden +++ b/test/fixtures/output/byok/describe-aws.golden @@ -1,12 +1,16 @@ -+------------+-----------------------------------------------------------------------------+ -| ID | cck-001 | -| Key | arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012 | -| Roles | arn:aws:iam::123456789012:role/role1, | -| | arn:aws:iam::123456789012:role/role2 | -| Cloud | AWS | -| State | IN_USE | -| Created At | 2022-11-12 08:24:00 +0000 UTC | -+------------+-----------------------------------------------------------------------------+ ++------------------+-----------------------------------------------------------------------------+ +| ID | cck-001 | +| Display Name | Production AWS Key | +| Key | arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012 | +| Roles | arn:aws:iam::123456789012:role/role1, | +| | arn:aws:iam::123456789012:role/role2 | +| Cloud | AWS | +| Region | us-east-1 | +| State | IN_USE | +| Created At | 2022-11-12 08:24:00 +0000 UTC | +| Validation Phase | VALID | +| Validation Since | 2022-11-12 08:30:00 +0000 UTC | ++------------------+-----------------------------------------------------------------------------+ Copy and append these permissions into the key policy "Statements" field of the ARN in your AWS key management system to authorize access for your Confluent Cloud cluster. diff --git a/test/fixtures/output/byok/describe-azure-json.golden b/test/fixtures/output/byok/describe-azure-json.golden index d20c46780e..6c711a55d9 100644 --- a/test/fixtures/output/byok/describe-azure-json.golden +++ b/test/fixtures/output/byok/describe-azure-json.golden @@ -1,8 +1,13 @@ { "id": "cck-003", + "display_name": "Azure Production Key", "key": "https://a-vault.vault.azure.net/keys/a-key", "roles": ["00000000-0000-0000-0000-000000000000"], "cloud": "Azure", + "region": "eastus", "state": "AVAILABLE", - "created_at": "2023-01-01 12:00:30 +0000 UTC" + "created_at": "2023-01-01 12:00:30 +0000 UTC", + "validation_phase": "INVALID", + "validation_since": "2023-01-01 12:05:30 +0000 UTC", + "message": "key access denied" } diff --git a/test/fixtures/output/byok/describe-azure.golden b/test/fixtures/output/byok/describe-azure.golden index 736f3506c5..13c753a641 100644 --- a/test/fixtures/output/byok/describe-azure.golden +++ b/test/fixtures/output/byok/describe-azure.golden @@ -1,11 +1,16 @@ -+------------+--------------------------------------------+ -| ID | cck-003 | -| Key | https://a-vault.vault.azure.net/keys/a-key | -| Roles | 00000000-0000-0000-0000-000000000000 | -| Cloud | Azure | -| State | AVAILABLE | -| Created At | 2023-01-01 12:00:30 +0000 UTC | -+------------+--------------------------------------------+ ++------------------+--------------------------------------------+ +| ID | cck-003 | +| Display Name | Azure Production Key | +| Key | https://a-vault.vault.azure.net/keys/a-key | +| Roles | 00000000-0000-0000-0000-000000000000 | +| Cloud | Azure | +| Region | eastus | +| State | AVAILABLE | +| Created At | 2023-01-01 12:00:30 +0000 UTC | +| Validation Phase | INVALID | +| Validation Since | 2023-01-01 12:05:30 +0000 UTC | +| Message | key access denied | ++------------------+--------------------------------------------+ To ensure the key vault has the correct role assignments, please run the following Azure CLI command (certified for `az` v2.45): diff --git a/test/fixtures/output/byok/describe-gcp-json.golden b/test/fixtures/output/byok/describe-gcp-json.golden index 76df32c173..8eca2f66a4 100644 --- a/test/fixtures/output/byok/describe-gcp-json.golden +++ b/test/fixtures/output/byok/describe-gcp-json.golden @@ -1,8 +1,12 @@ { "id": "cck-004", + "display_name": "GCP Test Key", "key": "projects/exampleproject/locations/us-central1/keyRings/testkeyring/cryptoKeys/testbyokkey/cryptoKeyVersions/3", "roles": [""], "cloud": "GCP", + "region": "us-central1", "state": "AVAILABLE", - "created_at": "2023-01-01 13:00:30 +0000 UTC" + "created_at": "2023-01-01 13:00:30 +0000 UTC", + "validation_phase": "VALID", + "validation_since": "2023-01-01 13:02:30 +0000 UTC" } diff --git a/test/fixtures/output/byok/describe-gcp.golden b/test/fixtures/output/byok/describe-gcp.golden index 9e5eeae641..baa0b3db79 100644 --- a/test/fixtures/output/byok/describe-gcp.golden +++ b/test/fixtures/output/byok/describe-gcp.golden @@ -1,11 +1,15 @@ -+------------+---------------------------------------------------------------------------------------------------------------+ -| ID | cck-004 | -| Key | projects/exampleproject/locations/us-central1/keyRings/testkeyring/cryptoKeys/testbyokkey/cryptoKeyVersions/3 | -| Roles | | -| Cloud | GCP | -| State | AVAILABLE | -| Created At | 2023-01-01 13:00:30 +0000 UTC | -+------------+---------------------------------------------------------------------------------------------------------------+ ++------------------+---------------------------------------------------------------------------------------------------------------+ +| ID | cck-004 | +| Display Name | GCP Test Key | +| Key | projects/exampleproject/locations/us-central1/keyRings/testkeyring/cryptoKeys/testbyokkey/cryptoKeyVersions/3 | +| Roles | | +| Cloud | GCP | +| Region | us-central1 | +| State | AVAILABLE | +| Created At | 2023-01-01 13:00:30 +0000 UTC | +| Validation Phase | VALID | +| Validation Since | 2023-01-01 13:02:30 +0000 UTC | ++------------------+---------------------------------------------------------------------------------------------------------------+ To ensure the key has the correct role assignments, please run the following Google Cloud CLI command: diff --git a/test/fixtures/output/byok/help.golden b/test/fixtures/output/byok/help.golden index 95d2cdd89e..ac74998100 100644 --- a/test/fixtures/output/byok/help.golden +++ b/test/fixtures/output/byok/help.golden @@ -8,6 +8,7 @@ Available Commands: delete Delete one or more self-managed keys. describe Describe a self-managed key. list List self-managed keys. + update Update a self-managed key. Global Flags: -h, --help Show help for this command. diff --git a/test/fixtures/output/byok/list-help.golden b/test/fixtures/output/byok/list-help.golden index a9f0e21aab..23ac743de6 100644 --- a/test/fixtures/output/byok/list-help.golden +++ b/test/fixtures/output/byok/list-help.golden @@ -4,9 +4,13 @@ Usage: confluent byok list [flags] Flags: - --cloud string Specify the cloud provider as "aws", "azure", or "gcp". - --state string Specify the state as "in-use" or "available". - -o, --output string Specify the output format as "human", "json", or "yaml". (default "human") + --cloud string Specify the cloud provider as "aws", "azure", or "gcp". + --state string Specify the state as "in-use" or "available". + --region string Filter by region. + --validation-phase string Specify the validation phase as "valid", "invalid", or "initializing". + --display-name string Filter by display name. + --key string Filter by key identifier. + -o, --output string Specify the output format as "human", "json", or "yaml". (default "human") Global Flags: -h, --help Show help for this command. diff --git a/test/fixtures/output/byok/list_1.golden b/test/fixtures/output/byok/list_1.golden index a22482ad9e..1aae68c032 100644 --- a/test/fixtures/output/byok/list_1.golden +++ b/test/fixtures/output/byok/list_1.golden @@ -1,6 +1,6 @@ - ID | Key | Cloud | State | Created At -----------+---------------------------------------------------------------------------------------------------------------+-------+-----------+-------------------------------- - cck-004 | projects/exampleproject/locations/us-central1/keyRings/testkeyring/cryptoKeys/testbyokkey/cryptoKeyVersions/3 | GCP | AVAILABLE | 2023-01-01 13:00:30 +0000 UTC - cck-003 | https://a-vault.vault.azure.net/keys/a-key | Azure | AVAILABLE | 2023-01-01 12:00:30 +0000 UTC - cck-001 | arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012 | AWS | IN_USE | 2022-11-12 08:24:00 +0000 UTC - cck-002 | arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012 | AWS | AVAILABLE | 2022-11-07 05:30:00 +0000 UTC + ID | Display Name | Key | Cloud | State | Created At | Validation Phase +----------+----------------------+---------------------------------------------------------------------------------------------------------------+-------+-----------+-------------------------------+------------------- + cck-004 | GCP Test Key | projects/exampleproject/locations/us-central1/keyRings/testkeyring/cryptoKeys/testbyokkey/cryptoKeyVersions/3 | GCP | AVAILABLE | 2023-01-01 13:00:30 +0000 UTC | VALID + cck-003 | Azure Production Key | https://a-vault.vault.azure.net/keys/a-key | Azure | AVAILABLE | 2023-01-01 12:00:30 +0000 UTC | INVALID + cck-001 | Production AWS Key | arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012 | AWS | IN_USE | 2022-11-12 08:24:00 +0000 UTC | VALID + cck-002 | Development AWS Key | arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012 | AWS | AVAILABLE | 2022-11-07 05:30:00 +0000 UTC | INITIALIZING diff --git a/test/fixtures/output/byok/list_2.golden b/test/fixtures/output/byok/list_2.golden index ff7763469d..5973ec1775 100644 --- a/test/fixtures/output/byok/list_2.golden +++ b/test/fixtures/output/byok/list_2.golden @@ -1,3 +1,3 @@ - ID | Key | Cloud | State | Created At -----------+-----------------------------------------------------------------------------+-------+--------+-------------------------------- - cck-001 | arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012 | AWS | IN_USE | 2022-11-12 08:24:00 +0000 UTC + ID | Display Name | Key | Cloud | State | Created At | Validation Phase +----------+--------------------+-----------------------------------------------------------------------------+-------+--------+-------------------------------+------------------- + cck-001 | Production AWS Key | arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012 | AWS | IN_USE | 2022-11-12 08:24:00 +0000 UTC | VALID diff --git a/test/fixtures/output/byok/list_3.golden b/test/fixtures/output/byok/list_3.golden index 573e7fa318..fd44bd5b68 100644 --- a/test/fixtures/output/byok/list_3.golden +++ b/test/fixtures/output/byok/list_3.golden @@ -1,4 +1,4 @@ - ID | Key | Cloud | State | Created At -----------+-----------------------------------------------------------------------------+-------+-----------+-------------------------------- - cck-001 | arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012 | AWS | IN_USE | 2022-11-12 08:24:00 +0000 UTC - cck-002 | arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012 | AWS | AVAILABLE | 2022-11-07 05:30:00 +0000 UTC + ID | Display Name | Key | Cloud | State | Created At | Validation Phase +----------+---------------------+-----------------------------------------------------------------------------+-------+-----------+-------------------------------+------------------- + cck-001 | Production AWS Key | arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012 | AWS | IN_USE | 2022-11-12 08:24:00 +0000 UTC | VALID + cck-002 | Development AWS Key | arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012 | AWS | AVAILABLE | 2022-11-07 05:30:00 +0000 UTC | INITIALIZING diff --git a/test/fixtures/output/byok/list_5.golden b/test/fixtures/output/byok/list_5.golden new file mode 100644 index 0000000000..5973ec1775 --- /dev/null +++ b/test/fixtures/output/byok/list_5.golden @@ -0,0 +1,3 @@ + ID | Display Name | Key | Cloud | State | Created At | Validation Phase +----------+--------------------+-----------------------------------------------------------------------------+-------+--------+-------------------------------+------------------- + cck-001 | Production AWS Key | arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012 | AWS | IN_USE | 2022-11-12 08:24:00 +0000 UTC | VALID diff --git a/test/fixtures/output/byok/list_6.golden b/test/fixtures/output/byok/list_6.golden new file mode 100644 index 0000000000..bdd7d6d492 --- /dev/null +++ b/test/fixtures/output/byok/list_6.golden @@ -0,0 +1,4 @@ + ID | Display Name | Key | Cloud | State | Created At | Validation Phase +----------+--------------------+---------------------------------------------------------------------------------------------------------------+-------+-----------+-------------------------------+------------------- + cck-004 | GCP Test Key | projects/exampleproject/locations/us-central1/keyRings/testkeyring/cryptoKeys/testbyokkey/cryptoKeyVersions/3 | GCP | AVAILABLE | 2023-01-01 13:00:30 +0000 UTC | VALID + cck-001 | Production AWS Key | arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012 | AWS | IN_USE | 2022-11-12 08:24:00 +0000 UTC | VALID diff --git a/test/fixtures/output/byok/list_7.golden b/test/fixtures/output/byok/list_7.golden new file mode 100644 index 0000000000..7d993c7b37 --- /dev/null +++ b/test/fixtures/output/byok/list_7.golden @@ -0,0 +1,3 @@ + ID | Display Name | Key | Cloud | State | Created At | Validation Phase +----------+---------------------+-----------------------------------------------------------------------------+-------+-----------+-------------------------------+------------------- + cck-002 | Development AWS Key | arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012 | AWS | AVAILABLE | 2022-11-07 05:30:00 +0000 UTC | INITIALIZING diff --git a/test/fixtures/output/byok/list_8.golden b/test/fixtures/output/byok/list_8.golden new file mode 100644 index 0000000000..8f656a7a1a --- /dev/null +++ b/test/fixtures/output/byok/list_8.golden @@ -0,0 +1,3 @@ + ID | Display Name | Key | Cloud | State | Created At | Validation Phase +----------+----------------------+--------------------------------------------+-------+-----------+-------------------------------+------------------- + cck-003 | Azure Production Key | https://a-vault.vault.azure.net/keys/a-key | Azure | AVAILABLE | 2023-01-01 12:00:30 +0000 UTC | INVALID diff --git a/test/fixtures/output/byok/update-fail.golden b/test/fixtures/output/byok/update-fail.golden new file mode 100644 index 0000000000..83e8f4863e --- /dev/null +++ b/test/fixtures/output/byok/update-fail.golden @@ -0,0 +1 @@ +Error: resource not found diff --git a/test/fixtures/output/byok/update-help.golden b/test/fixtures/output/byok/update-help.golden new file mode 100644 index 0000000000..1ad1274a49 --- /dev/null +++ b/test/fixtures/output/byok/update-help.golden @@ -0,0 +1,18 @@ +Update a self-managed key in Confluent Cloud. + +Usage: + confluent byok update [flags] + +Examples: +Update the display name of self-managed key "cck-12345". + + $ confluent byok update cck-12345 --display-name "My production key" + +Flags: + --display-name string REQUIRED: A human-readable name for the self-managed key. + -o, --output string Specify the output format as "human", "json", or "yaml". (default "human") + +Global Flags: + -h, --help Show help for this command. + --unsafe-trace Equivalent to -vvvv, but also log HTTP requests and responses which might contain plaintext secrets. + -v, --verbose count Increase verbosity (-v for warn, -vv for info, -vvv for debug, -vvvv for trace). diff --git a/test/fixtures/output/byok/update-success-json.golden b/test/fixtures/output/byok/update-success-json.golden new file mode 100644 index 0000000000..809da2e415 --- /dev/null +++ b/test/fixtures/output/byok/update-success-json.golden @@ -0,0 +1,15 @@ +{ + "id": "cck-001", + "display_name": "Updated Production Key", + "key": "arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012", + "roles": [ + "arn:aws:iam::123456789012:role/role1", + "arn:aws:iam::123456789012:role/role2" + ], + "cloud": "AWS", + "region": "us-east-1", + "state": "IN_USE", + "created_at": "2022-11-12 08:24:00 +0000 UTC", + "validation_phase": "VALID", + "validation_since": "2022-11-12 08:30:00 +0000 UTC" +} diff --git a/test/fixtures/output/byok/update-success.golden b/test/fixtures/output/byok/update-success.golden new file mode 100644 index 0000000000..8c92355bdc --- /dev/null +++ b/test/fixtures/output/byok/update-success.golden @@ -0,0 +1,39 @@ ++------------------+-----------------------------------------------------------------------------+ +| ID | cck-001 | +| Display Name | Updated Production Key | +| Key | arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012 | +| Roles | arn:aws:iam::123456789012:role/role1, | +| | arn:aws:iam::123456789012:role/role2 | +| Cloud | AWS | +| Region | us-east-1 | +| State | IN_USE | +| Created At | 2022-11-12 08:24:00 +0000 UTC | +| Validation Phase | VALID | +| Validation Since | 2022-11-12 08:30:00 +0000 UTC | ++------------------+-----------------------------------------------------------------------------+ + +Copy and append these permissions into the key policy "Statements" field of the ARN in your AWS key management system to authorize access for your Confluent Cloud cluster. + +{ + "Sid" : "Allow Confluent accounts to use the key", + "Effect" : "Allow", + "Principal" : { + "AWS" : [ + "arn:aws:iam::123456789012:role/role1", + "arn:aws:iam::123456789012:role/role2" + ] + }, + "Action" : [ "kms:Encrypt", "kms:Decrypt", "kms:ReEncrypt*", "kms:GenerateDataKey*", "kms:DescribeKey" ], + "Resource" : "*" +}, { + "Sid" : "Allow Confluent accounts to attach persistent resources", + "Effect" : "Allow", + "Principal" : { + "AWS" : [ + "arn:aws:iam::123456789012:role/role1", + "arn:aws:iam::123456789012:role/role2" + ] + }, + "Action" : [ "kms:CreateGrant", "kms:ListGrants", "kms:RevokeGrant" ], + "Resource" : "*" +} diff --git a/test/test-server/byok_handlers.go b/test/test-server/byok_handlers.go index 6b71c85c9d..00dbe6ab59 100644 --- a/test/test-server/byok_handlers.go +++ b/test/test-server/byok_handlers.go @@ -6,6 +6,7 @@ import ( "net/http" "net/url" "sort" + "strings" "testing" "time" @@ -24,6 +25,8 @@ func handleByokKey(t *testing.T) http.HandlerFunc { switch r.Method { case http.MethodGet: handleByokKeyGet(t, keyStr, byokStoreV1)(w, r) + case http.MethodPatch: + handleByokKeyUpdate(t, keyStr, byokStoreV1)(w, r) case http.MethodDelete: handleByokKeyDelete(t, keyStr, byokStoreV1)(w, r) } @@ -47,6 +50,30 @@ func handleByokKeyGet(t *testing.T, keyStr string, byokStoreV1 map[string]*byokv } } +func handleByokKeyUpdate(t *testing.T, keyStr string, byokStoreV1 map[string]*byokv1.ByokV1Key) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + // check if keystr exists in store + if existingKey, ok := byokStoreV1[keyStr]; !ok { + err := writeResourceNotFoundError(w) + require.NoError(t, err) + return + } else { + req := new(byokv1.ByokV1KeyUpdate) + err := json.NewDecoder(r.Body).Decode(req) + require.NoError(t, err) + + // Update the display name if provided + if req.DisplayName != nil { + existingKey.DisplayName = req.DisplayName + } + + // Return the updated key + err = json.NewEncoder(w).Encode(existingKey) + require.NoError(t, err) + } + } +} + func handleByokKeyDelete(t *testing.T, keyStr string, byokStoreV1 map[string]*byokv1.ByokV1Key) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { // check if keystr exists in store @@ -64,9 +91,10 @@ func handleByokKeyDelete(t *testing.T, keyStr string, byokStoreV1 map[string]*by func handleByokKeys(t *testing.T) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { byokStoreV1 := fillByokStoreV1() - if r.Method == http.MethodPost { + switch r.Method { + case http.MethodPost: handleByokKeysCreate(t, byokStoreV1)(w, r) - } else if r.Method == http.MethodGet { + case http.MethodGet: handleByokKeysList(t, byokStoreV1)(w, r) } } @@ -79,9 +107,14 @@ func handleByokKeysCreate(t *testing.T, byokStoreV1 map[string]*byokv1.ByokV1Key require.NoError(t, err) byokKey := &byokv1.ByokV1Key{ - Id: byokv1.PtrString(fmt.Sprintf("cck-%03d", 4)), - Metadata: &byokv1.ObjectMeta{CreatedAt: byokv1.PtrTime(time.Date(2022, time.December, 24, 0, 0, 0, 0, time.UTC))}, - State: byokv1.PtrString("AVAILABLE"), + Id: byokv1.PtrString(fmt.Sprintf("cck-%03d", 4)), + DisplayName: req.DisplayName, + Metadata: &byokv1.ObjectMeta{CreatedAt: byokv1.PtrTime(time.Date(2022, time.December, 24, 0, 0, 0, 0, time.UTC))}, + State: byokv1.PtrString("AVAILABLE"), + Validation: &byokv1.ByokV1KeyValidation{ + Phase: "INITIALIZING", + Since: time.Date(2022, time.December, 24, 0, 0, 0, 0, time.UTC), + }, } switch { @@ -138,11 +171,42 @@ func byokKeysFilterV1(url *url.URL, byokStoreV1 map[string]*byokv1.ByokV1Key) *b q := url.Query() provider := q.Get("provider") state := q.Get("state") + validationRegion := q.Get("validation_region") + validationPhase := q.Get("validation_phase") + displayName := q.Get("display_name") + keyIdentifier := q.Get("key") for _, key := range byokStoreV1 { providerFilter := provider == "" || provider == key.GetProvider() stateFilter := (state == "") || state == *key.State - if providerFilter && stateFilter { + displayNameFilter := displayName == "" || (key.DisplayName != nil && displayName == key.GetDisplayName()) + + // For keyIdentifier filter, check the appropriate field based on provider (partial matching) + keyIdentifierFilter := keyIdentifier == "" + if keyIdentifier != "" && key.Key != nil { + switch { + case key.Key.ByokV1AwsKey != nil: + keyIdentifierFilter = strings.Contains(key.Key.ByokV1AwsKey.GetKeyArn(), keyIdentifier) + case key.Key.ByokV1AzureKey != nil: + keyIdentifierFilter = strings.Contains(key.Key.ByokV1AzureKey.GetKeyId(), keyIdentifier) + case key.Key.ByokV1GcpKey != nil: + keyIdentifierFilter = strings.Contains(key.Key.ByokV1GcpKey.GetKeyId(), keyIdentifier) + } + } + + // For validation filters, check if validation exists and matches + validationRegionFilter := validationRegion == "" + validationPhaseFilter := validationPhase == "" + if key.Validation != nil { + if validationRegion != "" { + validationRegionFilter = validationRegion == key.Validation.GetRegion() + } + if validationPhase != "" { + validationPhaseFilter = validationPhase == key.Validation.GetPhase() + } + } + + if providerFilter && stateFilter && displayNameFilter && keyIdentifierFilter && validationRegionFilter && validationPhaseFilter { byokKeyList.Data = append(byokKeyList.Data, *key) } } diff --git a/test/test-server/utils.go b/test/test-server/utils.go index 49b84b5ba1..6d9333a63d 100644 --- a/test/test-server/utils.go +++ b/test/test-server/utils.go @@ -248,8 +248,9 @@ func fillByokStoreV1() map[string]*byokv1.ByokV1Key { byokStoreV1 := map[string]*byokv1.ByokV1Key{} byokStoreV1["cck-001"] = &byokv1.ByokV1Key{ - Id: byokv1.PtrString("cck-001"), - Metadata: &byokv1.ObjectMeta{CreatedAt: byokv1.PtrTime(time.Date(2022, time.November, 12, 8, 24, 0, 0, time.UTC))}, + Id: byokv1.PtrString("cck-001"), + DisplayName: byokv1.PtrString("Production AWS Key"), + Metadata: &byokv1.ObjectMeta{CreatedAt: byokv1.PtrTime(time.Date(2022, time.November, 12, 8, 24, 0, 0, time.UTC))}, Key: &byokv1.ByokV1KeyKeyOneOf{ ByokV1AwsKey: &byokv1.ByokV1AwsKey{ KeyArn: "arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012", @@ -262,11 +263,17 @@ func fillByokStoreV1() map[string]*byokv1.ByokV1Key { }, Provider: byokv1.PtrString("AWS"), State: byokv1.PtrString("IN_USE"), + Validation: &byokv1.ByokV1KeyValidation{ + Phase: "VALID", + Since: time.Date(2022, time.November, 12, 8, 30, 0, 0, time.UTC), + Region: byokv1.PtrString("us-east-1"), + }, } byokStoreV1["cck-002"] = &byokv1.ByokV1Key{ - Id: byokv1.PtrString("cck-002"), - Metadata: &byokv1.ObjectMeta{CreatedAt: byokv1.PtrTime(time.Date(2022, time.November, 7, 5, 30, 0, 0, time.UTC))}, + Id: byokv1.PtrString("cck-002"), + DisplayName: byokv1.PtrString("Development AWS Key"), + Metadata: &byokv1.ObjectMeta{CreatedAt: byokv1.PtrTime(time.Date(2022, time.November, 7, 5, 30, 0, 0, time.UTC))}, Key: &byokv1.ByokV1KeyKeyOneOf{ ByokV1AwsKey: &byokv1.ByokV1AwsKey{ KeyArn: "arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012", @@ -279,11 +286,16 @@ func fillByokStoreV1() map[string]*byokv1.ByokV1Key { }, Provider: byokv1.PtrString("AWS"), State: byokv1.PtrString("AVAILABLE"), + Validation: &byokv1.ByokV1KeyValidation{ + Phase: "INITIALIZING", + Since: time.Date(2022, time.November, 7, 5, 35, 0, 0, time.UTC), + }, } byokStoreV1["cck-003"] = &byokv1.ByokV1Key{ - Id: byokv1.PtrString("cck-003"), - Metadata: &byokv1.ObjectMeta{CreatedAt: byokv1.PtrTime(time.Date(2023, time.January, 1, 12, 0, 30, 0, time.UTC))}, + Id: byokv1.PtrString("cck-003"), + DisplayName: byokv1.PtrString("Azure Production Key"), + Metadata: &byokv1.ObjectMeta{CreatedAt: byokv1.PtrTime(time.Date(2023, time.January, 1, 12, 0, 30, 0, time.UTC))}, Key: &byokv1.ByokV1KeyKeyOneOf{ ByokV1AzureKey: &byokv1.ByokV1AzureKey{ ApplicationId: byokv1.PtrString("00000000-0000-0000-0000-000000000000"), @@ -295,11 +307,18 @@ func fillByokStoreV1() map[string]*byokv1.ByokV1Key { }, Provider: byokv1.PtrString("Azure"), State: byokv1.PtrString("AVAILABLE"), + Validation: &byokv1.ByokV1KeyValidation{ + Phase: "INVALID", + Since: time.Date(2023, time.January, 1, 12, 5, 30, 0, time.UTC), + Region: byokv1.PtrString("eastus"), + Message: byokv1.PtrString("key access denied"), + }, } byokStoreV1["cck-004"] = &byokv1.ByokV1Key{ - Id: byokv1.PtrString("cck-004"), - Metadata: &byokv1.ObjectMeta{CreatedAt: byokv1.PtrTime(time.Date(2023, time.January, 1, 13, 0, 30, 0, time.UTC))}, + Id: byokv1.PtrString("cck-004"), + DisplayName: byokv1.PtrString("GCP Test Key"), + Metadata: &byokv1.ObjectMeta{CreatedAt: byokv1.PtrTime(time.Date(2023, time.January, 1, 13, 0, 30, 0, time.UTC))}, Key: &byokv1.ByokV1KeyKeyOneOf{ ByokV1GcpKey: &byokv1.ByokV1GcpKey{ KeyId: "projects/exampleproject/locations/us-central1/keyRings/testkeyring/cryptoKeys/testbyokkey/cryptoKeyVersions/3", @@ -308,6 +327,11 @@ func fillByokStoreV1() map[string]*byokv1.ByokV1Key { }, Provider: byokv1.PtrString("GCP"), State: byokv1.PtrString("AVAILABLE"), + Validation: &byokv1.ByokV1KeyValidation{ + Phase: "VALID", + Since: time.Date(2023, time.January, 1, 13, 2, 30, 0, time.UTC), + Region: byokv1.PtrString("us-central1"), + }, } return byokStoreV1