From 7ee923b11acb659157ee9bc599fd1e5d3d7927c1 Mon Sep 17 00:00:00 2001 From: Jan Sternagel Date: Thu, 21 Aug 2025 06:40:41 +0200 Subject: [PATCH 01/52] pkg setup for kms --- internal/pkg/config/config.go | 3 + internal/pkg/services/kms/client/client.go | 45 +++ internal/pkg/services/kms/utils/utils.go | 47 ++++ internal/pkg/services/kms/utils/utils_test.go | 257 ++++++++++++++++++ 4 files changed, 352 insertions(+) create mode 100644 internal/pkg/services/kms/client/client.go create mode 100644 internal/pkg/services/kms/utils/utils.go create mode 100644 internal/pkg/services/kms/utils/utils_test.go diff --git a/internal/pkg/config/config.go b/internal/pkg/config/config.go index 957d7c475..a8c136996 100644 --- a/internal/pkg/config/config.go +++ b/internal/pkg/config/config.go @@ -36,6 +36,7 @@ const ( RedisCustomEndpointKey = "redis_custom_endpoint" ResourceManagerEndpointKey = "resource_manager_custom_endpoint" SecretsManagerCustomEndpointKey = "secrets_manager_custom_endpoint" + KMSCustomEndpointKey = "kms_custom_endpoint" ServiceAccountCustomEndpointKey = "service_account_custom_endpoint" ServiceEnablementCustomEndpointKey = "service_enablement_custom_endpoint" ServerBackupCustomEndpointKey = "serverbackup_custom_endpoint" @@ -95,6 +96,7 @@ var ConfigKeys = []string{ RedisCustomEndpointKey, ResourceManagerEndpointKey, SecretsManagerCustomEndpointKey, + KMSCustomEndpointKey, ServiceAccountCustomEndpointKey, ServiceEnablementCustomEndpointKey, ServerBackupCustomEndpointKey, @@ -180,6 +182,7 @@ func setConfigDefaults() { viper.SetDefault(PostgresFlexCustomEndpointKey, "") viper.SetDefault(ResourceManagerEndpointKey, "") viper.SetDefault(SecretsManagerCustomEndpointKey, "") + viper.SetDefault(KMSCustomEndpointKey, "") viper.SetDefault(ServiceAccountCustomEndpointKey, "") viper.SetDefault(ServiceEnablementCustomEndpointKey, "") viper.SetDefault(ServerBackupCustomEndpointKey, "") diff --git a/internal/pkg/services/kms/client/client.go b/internal/pkg/services/kms/client/client.go new file mode 100644 index 000000000..b2cbd8250 --- /dev/null +++ b/internal/pkg/services/kms/client/client.go @@ -0,0 +1,45 @@ +package client + +import ( + "github.com/stackitcloud/stackit-cli/internal/pkg/auth" + "github.com/stackitcloud/stackit-cli/internal/pkg/config" + "github.com/stackitcloud/stackit-cli/internal/pkg/errors" + "github.com/stackitcloud/stackit-cli/internal/pkg/print" + "github.com/stackitcloud/stackit-cli/internal/pkg/utils" + + "github.com/spf13/viper" + sdkConfig "github.com/stackitcloud/stackit-sdk-go/core/config" + "github.com/stackitcloud/stackit-sdk-go/services/kms" +) + +func ConfigureClient(p *print.Printer, cliVersion string) (*kms.APIClient, error) { + authCfgOption, err := auth.AuthenticationConfig(p, auth.AuthorizeUser) + if err != nil { + p.Debug(print.ErrorLevel, "configure authentication: %v", err) + return nil, &errors.AuthError{} + } + cfgOptions := []sdkConfig.ConfigurationOption{ + utils.UserAgentConfigOption(cliVersion), + authCfgOption, + } + + customEndpoint := viper.GetString(config.KMSCustomEndpointKey) + + if customEndpoint != "" { + cfgOptions = append(cfgOptions, sdkConfig.WithEndpoint(customEndpoint)) + } + + if p.IsVerbosityDebug() { + cfgOptions = append(cfgOptions, + sdkConfig.WithMiddleware(print.RequestResponseCapturer(p, nil)), + ) + } + + apiClient, err := kms.NewAPIClient(cfgOptions...) + if err != nil { + p.Debug(print.ErrorLevel, "create new API client: %v", err) + return nil, &errors.AuthError{} + } + + return apiClient, nil +} diff --git a/internal/pkg/services/kms/utils/utils.go b/internal/pkg/services/kms/utils/utils.go new file mode 100644 index 000000000..a3f111d8e --- /dev/null +++ b/internal/pkg/services/kms/utils/utils.go @@ -0,0 +1,47 @@ +package utils + +import ( + "context" + "fmt" + "time" + + "github.com/stackitcloud/stackit-sdk-go/services/kms" +) + +type KMSClient interface { + GetKeyExecute(ctx context.Context, projectId string, regionId string, keyRingId string, keyId string) (*kms.Key, error) + GetKeyRingExecute(ctx context.Context, projectId string, regionId string, keyRingId string) (*kms.KeyRing, error) + GetWrappingKeyExecute(ctx context.Context, projectId string, regionId string, keyRingId string, wrappingKeyId string) (*kms.WrappingKey, error) +} + +func GetKeyName(ctx context.Context, apiClient KMSClient, projectId, region, keyRingId, keyId string) (string, error) { + resp, err := apiClient.GetKeyExecute(ctx, projectId, region, keyRingId, keyId) + if err != nil { + return "", fmt.Errorf("get KMS Key: %w", err) + } + return *resp.DisplayName, nil +} + +func GetKeyDeletionDate(ctx context.Context, apiClient KMSClient, projectId, region, keyRingId, keyId string) (time.Time, error) { + resp, err := apiClient.GetKeyExecute(ctx, projectId, region, keyRingId, keyId) + if err != nil { + return time.Now(), fmt.Errorf("get KMS Key: %w", err) + } + return *resp.DeletionDate, nil +} + +func GetKeyRingName(ctx context.Context, apiClient KMSClient, projectId, id, region string) (string, error) { + resp, err := apiClient.GetKeyRingExecute(ctx, projectId, region, id) + if err != nil { + return "", fmt.Errorf("get KMS Key Ring: %w", err) + } + return *resp.DisplayName, nil +} + +func GetWrappingKeyName(ctx context.Context, apiClient KMSClient, projectId, region, keyRingId, wrappingKeyId string) (string, error) { + resp, err := apiClient.GetWrappingKeyExecute(ctx, projectId, region, keyRingId, wrappingKeyId) + if err != nil { + return "", fmt.Errorf("get KMS Wrapping Key: %w", err) + } + return *resp.DisplayName, nil +} diff --git a/internal/pkg/services/kms/utils/utils_test.go b/internal/pkg/services/kms/utils/utils_test.go new file mode 100644 index 000000000..cefe4cb9c --- /dev/null +++ b/internal/pkg/services/kms/utils/utils_test.go @@ -0,0 +1,257 @@ +package utils + +import ( + "context" + "fmt" + "testing" + "time" + + "github.com/google/uuid" + "github.com/stackitcloud/stackit-sdk-go/services/kms" +) + +var ( + testProjectId = uuid.NewString() + testRegion = "eu01" + testKeyRingId = uuid.NewString() + testKeyId = uuid.NewString() + testWrappingKeyId = uuid.NewString() +) + +const ( + testKeyName = "my-test-key" + testKeyRingName = "my-key-ring" + testWrappingKeyName = "my-wrapping-key" +) + +type kmsClientMocked struct { + getKeyFails bool + getKeyResp *kms.Key + getKeyRingFails bool + getKeyRingResp *kms.KeyRing + getWrappingKeyFails bool + getWrappingKeyResp *kms.WrappingKey +} + +// Implement the KMSClient interface methods for the mock. +func (m *kmsClientMocked) GetKeyExecute(_ context.Context, _, _, _, _ string) (*kms.Key, error) { + if m.getKeyFails { + return nil, fmt.Errorf("could not get key") + } + return m.getKeyResp, nil +} + +func (m *kmsClientMocked) GetKeyRingExecute(_ context.Context, _, _, _ string) (*kms.KeyRing, error) { + if m.getKeyRingFails { + return nil, fmt.Errorf("could not get key ring") + } + return m.getKeyRingResp, nil +} + +func (m *kmsClientMocked) GetWrappingKeyExecute(_ context.Context, _, _, _, _ string) (*kms.WrappingKey, error) { + if m.getWrappingKeyFails { + return nil, fmt.Errorf("could not get wrapping key") + } + return m.getWrappingKeyResp, nil +} + +func TestGetKeyName(t *testing.T) { + keyName := testKeyName + + tests := []struct { + description string + getKeyFails bool + getKeyResp *kms.Key + isValid bool + expectedOutput string + }{ + { + description: "base", + getKeyResp: &kms.Key{ + DisplayName: &keyName, + }, + isValid: true, + expectedOutput: testKeyName, + }, + { + description: "get key fails", + getKeyFails: true, + isValid: false, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + client := &kmsClientMocked{ + getKeyFails: tt.getKeyFails, + getKeyResp: tt.getKeyResp, + } + + output, err := GetKeyName(context.Background(), client, testProjectId, testRegion, testKeyRingId, testKeyId) + + if tt.isValid && err != nil { + t.Errorf("failed on valid input: %v", err) + } + if !tt.isValid && err == nil { + t.Errorf("did not fail on invalid input") + } + if !tt.isValid { + return + } + if output != tt.expectedOutput { + t.Errorf("expected output to be %q, got %q", tt.expectedOutput, output) + } + }) + } +} + +// TestGetKeyDeletionDate tests the GetKeyDeletionDate function. +func TestGetKeyDeletionDate(t *testing.T) { + mockTime := time.Date(2025, 8, 20, 0, 0, 0, 0, time.UTC) + + tests := []struct { + description string + getKeyFails bool + getKeyResp *kms.Key + isValid bool + expectedOutput time.Time + }{ + { + description: "base", + getKeyResp: &kms.Key{ + DeletionDate: &mockTime, + }, + isValid: true, + expectedOutput: mockTime, + }, + { + description: "get key fails", + getKeyFails: true, + isValid: false, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + client := &kmsClientMocked{ + getKeyFails: tt.getKeyFails, + getKeyResp: tt.getKeyResp, + } + + output, err := GetKeyDeletionDate(context.Background(), client, testProjectId, testRegion, testKeyRingId, testKeyId) + + if tt.isValid && err != nil { + t.Errorf("failed on valid input: %v", err) + } + if !tt.isValid && err == nil { + t.Errorf("did not fail on invalid input") + } + if !tt.isValid { + return + } + if !output.Equal(tt.expectedOutput) { + t.Errorf("expected output to be %v, got %v", tt.expectedOutput, output) + } + }) + } +} + +// TestGetKeyRingName tests the GetKeyRingName function. +func TestGetKeyRingName(t *testing.T) { + keyRingName := testKeyRingName + + tests := []struct { + description string + getKeyRingFails bool + getKeyRingResp *kms.KeyRing + isValid bool + expectedOutput string + }{ + { + description: "base", + getKeyRingResp: &kms.KeyRing{ + DisplayName: &keyRingName, + }, + isValid: true, + expectedOutput: testKeyRingName, + }, + { + description: "get key ring fails", + getKeyRingFails: true, + isValid: false, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + client := &kmsClientMocked{ + getKeyRingFails: tt.getKeyRingFails, + getKeyRingResp: tt.getKeyRingResp, + } + + output, err := GetKeyRingName(context.Background(), client, testProjectId, testKeyRingId, testRegion) + + if tt.isValid && err != nil { + t.Errorf("failed on valid input: %v", err) + } + if !tt.isValid && err == nil { + t.Errorf("did not fail on invalid input") + } + if !tt.isValid { + return + } + if output != tt.expectedOutput { + t.Errorf("expected output to be %q, got %q", tt.expectedOutput, output) + } + }) + } +} + +func TestGetWrappingKeyName(t *testing.T) { + wrappingKeyName := testWrappingKeyName + tests := []struct { + description string + getWrappingKeyFails bool + getWrappingKeyResp *kms.WrappingKey + isValid bool + expectedOutput string + }{ + { + description: "base", + getWrappingKeyResp: &kms.WrappingKey{ + DisplayName: &wrappingKeyName, + }, + isValid: true, + expectedOutput: testWrappingKeyName, + }, + { + description: "get wrapping key fails", + getWrappingKeyFails: true, + isValid: false, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + client := &kmsClientMocked{ + getWrappingKeyFails: tt.getWrappingKeyFails, + getWrappingKeyResp: tt.getWrappingKeyResp, + } + + output, err := GetWrappingKeyName(context.Background(), client, testProjectId, testRegion, testKeyRingId, testWrappingKeyId) + + if tt.isValid && err != nil { + t.Errorf("failed on valid input: %v", err) + } + if !tt.isValid && err == nil { + t.Errorf("did not fail on invalid input") + } + if !tt.isValid { + return + } + if output != tt.expectedOutput { + t.Errorf("expected output to be %q, got %q", tt.expectedOutput, output) + } + }) + } +} From 5a7af4fd515fbe09813b1cc21a2e9a8dd74f21a1 Mon Sep 17 00:00:00 2001 From: Jan Sternagel Date: Thu, 21 Aug 2025 06:41:19 +0200 Subject: [PATCH 02/52] cmd config setup --- internal/cmd/config/set/set.go | 4 ++++ internal/cmd/config/unset/unset.go | 7 +++++++ internal/cmd/config/unset/unset_test.go | 13 +++++++++++++ 3 files changed, 24 insertions(+) diff --git a/internal/cmd/config/set/set.go b/internal/cmd/config/set/set.go index 54f9f527d..8ca00a2fd 100644 --- a/internal/cmd/config/set/set.go +++ b/internal/cmd/config/set/set.go @@ -37,6 +37,7 @@ const ( redisCustomEndpointFlag = "redis-custom-endpoint" resourceManagerCustomEndpointFlag = "resource-manager-custom-endpoint" secretsManagerCustomEndpointFlag = "secrets-manager-custom-endpoint" + kmsCustomEndpointFlag = "kms-custom-endpoint" serverBackupCustomEndpointFlag = "serverbackup-custom-endpoint" serverOsUpdateCustomEndpointFlag = "server-osupdate-custom-endpoint" runCommandCustomEndpointFlag = "runcommand-custom-endpoint" @@ -150,6 +151,7 @@ func configureFlags(cmd *cobra.Command) { cmd.Flags().String(redisCustomEndpointFlag, "", "Redis API base URL, used in calls to this API") cmd.Flags().String(resourceManagerCustomEndpointFlag, "", "Resource Manager API base URL, used in calls to this API") cmd.Flags().String(secretsManagerCustomEndpointFlag, "", "Secrets Manager API base URL, used in calls to this API") + cmd.Flags().String(kmsCustomEndpointFlag, "", "KMS API base URL, used in calls to this API") cmd.Flags().String(serviceAccountCustomEndpointFlag, "", "Service Account API base URL, used in calls to this API") cmd.Flags().String(serviceEnablementCustomEndpointFlag, "", "Service Enablement API base URL, used in calls to this API") cmd.Flags().String(serverBackupCustomEndpointFlag, "", "Server Backup API base URL, used in calls to this API") @@ -197,6 +199,8 @@ func configureFlags(cmd *cobra.Command) { cobra.CheckErr(err) err = viper.BindPFlag(config.SecretsManagerCustomEndpointKey, cmd.Flags().Lookup(secretsManagerCustomEndpointFlag)) cobra.CheckErr(err) + err = viper.BindPFlag(config.KMSCustomEndpointKey, cmd.Flags().Lookup(kmsCustomEndpointFlag)) + cobra.CheckErr(err) err = viper.BindPFlag(config.ServerBackupCustomEndpointKey, cmd.Flags().Lookup(serverBackupCustomEndpointFlag)) cobra.CheckErr(err) err = viper.BindPFlag(config.ServerOsUpdateCustomEndpointKey, cmd.Flags().Lookup(serverOsUpdateCustomEndpointFlag)) diff --git a/internal/cmd/config/unset/unset.go b/internal/cmd/config/unset/unset.go index a288be6a3..6d85680d1 100644 --- a/internal/cmd/config/unset/unset.go +++ b/internal/cmd/config/unset/unset.go @@ -41,6 +41,7 @@ const ( redisCustomEndpointFlag = "redis-custom-endpoint" resourceManagerCustomEndpointFlag = "resource-manager-custom-endpoint" secretsManagerCustomEndpointFlag = "secrets-manager-custom-endpoint" + kmsCustomEndpointFlag = "kms-custom-endpoint" serviceAccountCustomEndpointFlag = "service-account-custom-endpoint" serviceEnablementCustomEndpointFlag = "service-enablement-custom-endpoint" serverBackupCustomEndpointFlag = "serverbackup-custom-endpoint" @@ -78,6 +79,7 @@ type inputModel struct { RedisCustomEndpoint bool ResourceManagerCustomEndpoint bool SecretsManagerCustomEndpoint bool + KMSCustomEndpoint bool ServerBackupCustomEndpoint bool ServerOsUpdateCustomEndpoint bool RunCommandCustomEndpoint bool @@ -180,6 +182,9 @@ func NewCmd(params *params.CmdParams) *cobra.Command { if model.SecretsManagerCustomEndpoint { viper.Set(config.SecretsManagerCustomEndpointKey, "") } + if model.KMSCustomEndpoint { + viper.Set(config.KMSCustomEndpointKey, "") + } if model.ServiceAccountCustomEndpoint { viper.Set(config.ServiceAccountCustomEndpointKey, "") } @@ -245,6 +250,7 @@ func configureFlags(cmd *cobra.Command) { cmd.Flags().Bool(redisCustomEndpointFlag, false, "Redis API base URL. If unset, uses the default base URL") cmd.Flags().Bool(resourceManagerCustomEndpointFlag, false, "Resource Manager API base URL. If unset, uses the default base URL") cmd.Flags().Bool(secretsManagerCustomEndpointFlag, false, "Secrets Manager API base URL. If unset, uses the default base URL") + cmd.Flags().Bool(kmsCustomEndpointFlag, false, "KMS API base URL. If unset, uses the default base URL") cmd.Flags().Bool(serviceAccountCustomEndpointFlag, false, "Service Account API base URL. If unset, uses the default base URL") cmd.Flags().Bool(serviceEnablementCustomEndpointFlag, false, "Service Enablement API base URL. If unset, uses the default base URL") cmd.Flags().Bool(serverBackupCustomEndpointFlag, false, "Server Backup base URL. If unset, uses the default base URL") @@ -283,6 +289,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command) *inputModel { RedisCustomEndpoint: flags.FlagToBoolValue(p, cmd, redisCustomEndpointFlag), ResourceManagerCustomEndpoint: flags.FlagToBoolValue(p, cmd, resourceManagerCustomEndpointFlag), SecretsManagerCustomEndpoint: flags.FlagToBoolValue(p, cmd, secretsManagerCustomEndpointFlag), + KMSCustomEndpoint: flags.FlagToBoolValue(p, cmd, kmsCustomEndpointFlag), ServiceAccountCustomEndpoint: flags.FlagToBoolValue(p, cmd, serviceAccountCustomEndpointFlag), ServiceEnablementCustomEndpoint: flags.FlagToBoolValue(p, cmd, serviceEnablementCustomEndpointFlag), ServerBackupCustomEndpoint: flags.FlagToBoolValue(p, cmd, serverBackupCustomEndpointFlag), diff --git a/internal/cmd/config/unset/unset_test.go b/internal/cmd/config/unset/unset_test.go index 246696f15..e48dff384 100644 --- a/internal/cmd/config/unset/unset_test.go +++ b/internal/cmd/config/unset/unset_test.go @@ -35,6 +35,7 @@ func fixtureFlagValues(mods ...func(flagValues map[string]bool)) map[string]bool redisCustomEndpointFlag: true, resourceManagerCustomEndpointFlag: true, secretsManagerCustomEndpointFlag: true, + kmsCustomEndpointFlag: true, serviceAccountCustomEndpointFlag: true, serverBackupCustomEndpointFlag: true, serverOsUpdateCustomEndpointFlag: true, @@ -74,6 +75,7 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { RedisCustomEndpoint: true, ResourceManagerCustomEndpoint: true, SecretsManagerCustomEndpoint: true, + KMSCustomEndpoint: true, ServiceAccountCustomEndpoint: true, ServerBackupCustomEndpoint: true, ServerOsUpdateCustomEndpoint: true, @@ -129,6 +131,7 @@ func TestParseInput(t *testing.T) { model.RedisCustomEndpoint = false model.ResourceManagerCustomEndpoint = false model.SecretsManagerCustomEndpoint = false + model.KMSCustomEndpoint = false model.ServiceAccountCustomEndpoint = false model.ServerBackupCustomEndpoint = false model.ServerOsUpdateCustomEndpoint = false @@ -219,6 +222,16 @@ func TestParseInput(t *testing.T) { model.SecretsManagerCustomEndpoint = false }), }, + { + description: "kms custom endpoint empty", + flagValues: fixtureFlagValues(func(flagValues map[string]bool) { + flagValues[kmsCustomEndpointFlag] = false + }), + isValid: true, + expectedModel: fixtureInputModel(func(model *inputModel) { + model.KMSCustomEndpoint = false + }), + }, { description: "service account custom endpoint empty", flagValues: fixtureFlagValues(func(flagValues map[string]bool) { From 72a60d69f175b3cce5bc2239cfa2b68749912c31 Mon Sep 17 00:00:00 2001 From: Jan Sternagel Date: Thu, 21 Aug 2025 06:42:05 +0200 Subject: [PATCH 03/52] beta kms cmd added --- internal/cmd/beta/kms/key/create/create.go | 196 +++++++++++++++++ internal/cmd/beta/kms/key/delete/delete.go | 140 ++++++++++++ .../cmd/beta/kms/key/importKey/importKey.go | 181 ++++++++++++++++ internal/cmd/beta/kms/key/key.go | 36 ++++ internal/cmd/beta/kms/key/list/list.go | 149 +++++++++++++ internal/cmd/beta/kms/key/restore/restore.go | 133 ++++++++++++ internal/cmd/beta/kms/key/rotate/rotate.go | 162 ++++++++++++++ .../cmd/beta/kms/keyring/create/create.go | 187 ++++++++++++++++ .../cmd/beta/kms/keyring/delete/delete.go | 112 ++++++++++ internal/cmd/beta/kms/keyring/keyring.go | 30 +++ internal/cmd/beta/kms/keyring/list/list.go | 138 ++++++++++++ internal/cmd/beta/kms/kms.go | 32 +++ .../cmd/beta/kms/version/destroy/destroy.go | 116 ++++++++++ .../cmd/beta/kms/version/disable/disable.go | 130 +++++++++++ .../cmd/beta/kms/version/enable/enable.go | 130 +++++++++++ internal/cmd/beta/kms/version/list/list.go | 157 ++++++++++++++ .../cmd/beta/kms/version/restore/restore.go | 117 ++++++++++ internal/cmd/beta/kms/version/version.go | 34 +++ .../cmd/beta/kms/wrappingkey/create/create.go | 203 ++++++++++++++++++ .../cmd/beta/kms/wrappingkey/delete/delete.go | 136 ++++++++++++ .../cmd/beta/kms/wrappingkey/list/list.go | 149 +++++++++++++ .../cmd/beta/kms/wrappingkey/wrappingkey.go | 30 +++ 22 files changed, 2698 insertions(+) create mode 100644 internal/cmd/beta/kms/key/create/create.go create mode 100644 internal/cmd/beta/kms/key/delete/delete.go create mode 100644 internal/cmd/beta/kms/key/importKey/importKey.go create mode 100644 internal/cmd/beta/kms/key/key.go create mode 100644 internal/cmd/beta/kms/key/list/list.go create mode 100644 internal/cmd/beta/kms/key/restore/restore.go create mode 100644 internal/cmd/beta/kms/key/rotate/rotate.go create mode 100644 internal/cmd/beta/kms/keyring/create/create.go create mode 100644 internal/cmd/beta/kms/keyring/delete/delete.go create mode 100644 internal/cmd/beta/kms/keyring/keyring.go create mode 100644 internal/cmd/beta/kms/keyring/list/list.go create mode 100644 internal/cmd/beta/kms/kms.go create mode 100644 internal/cmd/beta/kms/version/destroy/destroy.go create mode 100644 internal/cmd/beta/kms/version/disable/disable.go create mode 100644 internal/cmd/beta/kms/version/enable/enable.go create mode 100644 internal/cmd/beta/kms/version/list/list.go create mode 100644 internal/cmd/beta/kms/version/restore/restore.go create mode 100644 internal/cmd/beta/kms/version/version.go create mode 100644 internal/cmd/beta/kms/wrappingkey/create/create.go create mode 100644 internal/cmd/beta/kms/wrappingkey/delete/delete.go create mode 100644 internal/cmd/beta/kms/wrappingkey/list/list.go create mode 100644 internal/cmd/beta/kms/wrappingkey/wrappingkey.go diff --git a/internal/cmd/beta/kms/key/create/create.go b/internal/cmd/beta/kms/key/create/create.go new file mode 100644 index 000000000..1c5407545 --- /dev/null +++ b/internal/cmd/beta/kms/key/create/create.go @@ -0,0 +1,196 @@ +package create + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/goccy/go-yaml" + "github.com/spf13/cobra" + "github.com/stackitcloud/stackit-cli/internal/cmd/params" + "github.com/stackitcloud/stackit-cli/internal/pkg/args" + cliErr "github.com/stackitcloud/stackit-cli/internal/pkg/errors" + "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/client" + + "github.com/stackitcloud/stackit-cli/internal/pkg/examples" + "github.com/stackitcloud/stackit-cli/internal/pkg/flags" + "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" + "github.com/stackitcloud/stackit-cli/internal/pkg/print" + "github.com/stackitcloud/stackit-cli/internal/pkg/projectname" + "github.com/stackitcloud/stackit-cli/internal/pkg/utils" + "github.com/stackitcloud/stackit-sdk-go/services/kms" +) + +const ( + keyRingIdFlag = "key-ring" + + algorithmFlag = "algorithm" + backendFlag = "backend" + descriptionFlag = "description" + displayNameFlag = "name" + importOnlyFlag = "import-only" + purposeFlag = "purpose" +) + +type inputModel struct { + *globalflags.GlobalFlagModel + KeyRingId string + + Algorithm *string + Backend string // Keep "backend" as a variable, but set the default to "software" (see UI) + Description *string + Name *string + ImportOnly *bool // Default false + Purpose *string +} + +func NewCmd(params *params.CmdParams) *cobra.Command { + cmd := &cobra.Command{ + Use: "create", + Short: "Creates a KMS Key", + Long: "Creates a KMS Key.", + Args: args.NoArgs, + Example: examples.Build( + examples.NewExample( + `Create a Symmetric KMS Key`, + `$ stakit beta kms key create --key-ring "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-key-name" --purpose "symmetric_encrypt_decrypt"`), + examples.NewExample( + `Create a Message Authentication KMS Key`, + `$ stakit beta kms key create --key-ring "my-keyring-id" --algorithm "hmac_sha512" --name "my-key-name" --purpose "message_authentication_code"`), + ), + RunE: func(cmd *cobra.Command, _ []string) error { + ctx := context.Background() + model, err := parseInput(params.Printer, cmd) + if err != nil { + return err + } + + // Configure API client + apiClient, err := client.ConfigureClient(params.Printer, params.CliVersion) + if err != nil { + return err + } + + projectLabel, err := projectname.GetProjectName(ctx, params.Printer, params.CliVersion, cmd) + if err != nil { + params.Printer.Debug(print.ErrorLevel, "get project name: %v", err) + projectLabel = model.ProjectId + } + + if !model.AssumeYes { + prompt := fmt.Sprintf("Are you sure you want to create a KMS Key for project %q?", projectLabel) + err = params.Printer.PromptForConfirmation(prompt) + if err != nil { + return err + } + } + + // Call API + req, _ := buildRequest(ctx, model, apiClient) + if err != nil { + return err + } + + key, err := req.Execute() + if err != nil { + return fmt.Errorf("create KMS Key: %w", err) + } + + // No wait exists for the key creation + return outputResult(params.Printer, model.OutputFormat, projectLabel, key) + }, + } + configureFlags(cmd) + return cmd +} + +func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { + globalFlags := globalflags.Parse(p, cmd) + if globalFlags.ProjectId == "" { + return nil, &cliErr.ProjectIdError{} + } + + // What checks could this need? + // I would rather let the creation fail instead of checking all possible algorithms + model := inputModel{ + GlobalFlagModel: globalFlags, + KeyRingId: flags.FlagToStringValue(p, cmd, keyRingIdFlag), + Algorithm: flags.FlagToStringPointer(p, cmd, algorithmFlag), + Backend: flags.FlagWithDefaultToStringValue(p, cmd, backendFlag), + Name: flags.FlagToStringPointer(p, cmd, displayNameFlag), + Description: flags.FlagToStringPointer(p, cmd, descriptionFlag), + ImportOnly: flags.FlagToBoolPointer(p, cmd, importOnlyFlag), + Purpose: flags.FlagToStringPointer(p, cmd, purposeFlag), + } + + if p.IsVerbosityDebug() { + modelStr, err := print.BuildDebugStrFromInputModel(model) + if err != nil { + p.Debug(print.ErrorLevel, "convert model to string for debugging: %v", err) + } else { + p.Debug(print.ErrorLevel, "parsed input values: %s", modelStr) + } + } + + return &model, nil +} + +type kmsKeyClient interface { + CreateKey(ctx context.Context, projectId string, regionId string, keyRingId string) kms.ApiCreateKeyRequest +} + +func buildRequest(ctx context.Context, model *inputModel, apiClient kmsKeyClient) (kms.ApiCreateKeyRequest, error) { + req := apiClient.CreateKey(ctx, model.ProjectId, model.Region, model.KeyRingId) + + // Question: Should there be additional checks here? + req = req.CreateKeyPayload(kms.CreateKeyPayload{ + DisplayName: model.Name, + Description: model.Description, + Algorithm: kms.CreateKeyPayloadGetAlgorithmAttributeType(model.Algorithm), + Backend: kms.CreateKeyPayloadGetBackendAttributeType(&model.Backend), + Purpose: kms.CreateKeyPayloadGetPurposeAttributeType(model.Purpose), + ImportOnly: model.ImportOnly, + }) + return req, nil +} + +func outputResult(p *print.Printer, outputFormat, projectLabel string, resp *kms.Key) error { + if resp == nil { + return fmt.Errorf("response is nil") + } + + switch outputFormat { + case print.JSONOutputFormat: + details, err := json.MarshalIndent(resp, "", " ") + if err != nil { + return fmt.Errorf("marshal KMS Key: %w", err) + } + p.Outputln(string(details)) + return nil + + case print.YAMLOutputFormat: + details, err := yaml.MarshalWithOptions(resp, yaml.IndentSequence(true), yaml.UseJSONMarshaler()) + if err != nil { + return fmt.Errorf("marshal KMS Key: %w", err) + } + p.Outputln(string(details)) + return nil + + default: + p.Outputf("Created Key for project %q. Key ID: %s\n", projectLabel, utils.PtrString(resp.Id)) + return nil + } +} + +func configureFlags(cmd *cobra.Command) { + cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS Key Ring") + cmd.Flags().String(algorithmFlag, "", "En-/Decryption / signing algorithm") + cmd.Flags().String(backendFlag, "software", "The backend that is responsible for maintaining this key") + cmd.Flags().String(displayNameFlag, "", "The display name to distinguish multiple keys") + cmd.Flags().String(descriptionFlag, "", "Optinal description of the Key") + cmd.Flags().Bool(importOnlyFlag, false, "States whether versions can be created or only imported") + cmd.Flags().String(purposeFlag, "", "Purpose of the Key. Enum: 'symmetric_encrypt_decrypt', 'asymmetric_encrypt_decrypt', 'message_authentication_code', 'asymmetric_sign_verify' ") + + err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, algorithmFlag, purposeFlag, displayNameFlag) + cobra.CheckErr(err) +} diff --git a/internal/cmd/beta/kms/key/delete/delete.go b/internal/cmd/beta/kms/key/delete/delete.go new file mode 100644 index 000000000..ddb60c137 --- /dev/null +++ b/internal/cmd/beta/kms/key/delete/delete.go @@ -0,0 +1,140 @@ +package delete + +import ( + "context" + "fmt" + + "github.com/spf13/cobra" + "github.com/stackitcloud/stackit-cli/internal/cmd/params" + "github.com/stackitcloud/stackit-cli/internal/pkg/args" + "github.com/stackitcloud/stackit-cli/internal/pkg/errors" + "github.com/stackitcloud/stackit-cli/internal/pkg/examples" + "github.com/stackitcloud/stackit-cli/internal/pkg/flags" + "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" + "github.com/stackitcloud/stackit-cli/internal/pkg/print" + kmsUtils "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/utils" + + "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/client" + "github.com/stackitcloud/stackit-cli/internal/pkg/utils" + "github.com/stackitcloud/stackit-sdk-go/services/kms" +) + +const ( + keyRingIdFlag = "key-ring" + keyIdFlag = "key" +) + +type inputModel struct { + *globalflags.GlobalFlagModel + KeyRingId string + KeyId string +} + +func NewCmd(params *params.CmdParams) *cobra.Command { + cmd := &cobra.Command{ + Use: "delete", + Short: "Deletes a KMS Key", + Long: "Deletes a KMS Key inside a specific Key Ring.", + Args: args.NoArgs, + Example: examples.Build( + examples.NewExample( + `Delete a KMS Key "my-key-id" inside the Key Ring "my-key-ring-id"`, + `$ stackit beta kms keyring delete --key-ring "my-key-ring-id" --key "my-key-id"`), + ), + RunE: func(cmd *cobra.Command, _ []string) error { + ctx := context.Background() + model, err := parseInput(params.Printer, cmd) + if err != nil { + return err + } + + // Configure API client + apiClient, err := client.ConfigureClient(params.Printer, params.CliVersion) + if err != nil { + return err + } + + keyName, err := kmsUtils.GetKeyName(ctx, apiClient, model.ProjectId, model.Region, model.KeyRingId, model.KeyId) + if err != nil { + params.Printer.Debug(print.ErrorLevel, "get key name: %v", err) + keyName = model.KeyId + } + + if !model.AssumeYes { + prompt := fmt.Sprintf("Are you sure you want to delete key %q? (This cannot be undone)", keyName) + err = params.Printer.PromptForConfirmation(prompt) + if err != nil { + return err + } + } + + // Call API + req := buildRequest(ctx, model, apiClient) + err = req.Execute() + if err != nil { + return fmt.Errorf("delete KMS Key: %w", err) + } + + // Don't wait for a month until the deletion was performed. + // Just print the deletion date. + deletionDate, err := kmsUtils.GetKeyDeletionDate(ctx, apiClient, model.ProjectId, model.Region, model.KeyRingId, model.KeyId) + if err != nil { + return err + } + + params.Printer.Info("Deletion of KMS Key %q scheduled successfully for the deletion date: %q\n", keyName, deletionDate) + return nil + }, + } + + configureFlags(cmd) + return cmd +} + +func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { + globalFlags := globalflags.Parse(p, cmd) + if globalFlags.ProjectId == "" { + return nil, &errors.ProjectIdError{} + } + + keyRingId := flags.FlagToStringValue(p, cmd, keyRingIdFlag) + keyId := flags.FlagToStringValue(p, cmd, keyIdFlag) + + // Validate the uuid format of the IDs + errKeyRing := utils.ValidateUUID(keyRingId) + errKey := utils.ValidateUUID(keyId) + if errKeyRing != nil || errKey != nil { + return nil, &errors.DSAInputPlanError{ + Cmd: cmd, + } + } + + model := inputModel{ + GlobalFlagModel: globalFlags, + KeyRingId: keyRingId, + KeyId: keyId, + } + + if p.IsVerbosityDebug() { + modelStr, err := print.BuildDebugStrFromInputModel(model) + if err != nil { + p.Debug(print.ErrorLevel, "convert model to string for debugging: %v", err) + } else { + p.Debug(print.DebugLevel, "parsed input values: %s", modelStr) + } + } + + return &model, nil +} + +func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClient) kms.ApiDeleteKeyRequest { + req := apiClient.DeleteKey(ctx, model.ProjectId, model.Region, model.KeyRingId, model.KeyId) + return req +} + +func configureFlags(cmd *cobra.Command) { + cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS Key Ring where the Key is stored") + cmd.Flags().Var(flags.UUIDFlag(), keyIdFlag, "ID of the actual Key") + err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, keyIdFlag) + cobra.CheckErr(err) +} diff --git a/internal/cmd/beta/kms/key/importKey/importKey.go b/internal/cmd/beta/kms/key/importKey/importKey.go new file mode 100644 index 000000000..aab53fe96 --- /dev/null +++ b/internal/cmd/beta/kms/key/importKey/importKey.go @@ -0,0 +1,181 @@ +package importKey + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/goccy/go-yaml" + "github.com/spf13/cobra" + "github.com/stackitcloud/stackit-cli/internal/cmd/params" + "github.com/stackitcloud/stackit-cli/internal/pkg/args" + cliErr "github.com/stackitcloud/stackit-cli/internal/pkg/errors" + "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/client" + kmsUtils "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/utils" + + "github.com/stackitcloud/stackit-cli/internal/pkg/examples" + "github.com/stackitcloud/stackit-cli/internal/pkg/flags" + "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" + "github.com/stackitcloud/stackit-cli/internal/pkg/print" + "github.com/stackitcloud/stackit-sdk-go/services/kms" +) + +const ( + keyRingIdFlag = "key-ring" + keyIdFlag = "key" + + wrappedKeyFlag = "wrapped-key" + wrappingKeyIdFlag = "wrapping-key-id" +) + +type inputModel struct { + *globalflags.GlobalFlagModel + KeyRingId string + KeyId string + + WrappedKey *string + WrappingKeyId *string +} + +func NewCmd(params *params.CmdParams) *cobra.Command { + cmd := &cobra.Command{ + Use: "import", + Short: "Import a KMS Key Version", + Long: "Improt a new version to the given KMS key.", + Args: args.NoArgs, + Example: examples.Build( + examples.NewExample( + `Import a new version for the given KMS Key "my-key"`, + `$ stakit beta kms key improt --key-ring "my-keyring-id" --key "my-key-id" --wrapped-key "base64-encoded-wrapped-key-material" --wrapping-key-id "my-wrapping-key-id"`), + ), + RunE: func(cmd *cobra.Command, _ []string) error { + ctx := context.Background() + model, err := parseInput(params.Printer, cmd) + if err != nil { + return err + } + + // Configure API client + apiClient, err := client.ConfigureClient(params.Printer, params.CliVersion) + if err != nil { + return err + } + + keyName, err := kmsUtils.GetKeyName(ctx, apiClient, model.ProjectId, model.Region, model.KeyRingId, model.KeyId) + if err != nil { + params.Printer.Debug(print.ErrorLevel, "get Key name: %v", err) + keyName = model.KeyId + } + keyRingName, err := kmsUtils.GetKeyRingName(ctx, apiClient, model.ProjectId, model.KeyRingId, model.Region) + if err != nil { + params.Printer.Debug(print.ErrorLevel, "get Key Ring name: %v", err) + keyRingName = model.KeyRingId + } + + if !model.AssumeYes { + prompt := fmt.Sprintf("Are you sure you want to import a new version for the KMS Key %q inside the Key Ring %q?", keyName, keyRingName) + err = params.Printer.PromptForConfirmation(prompt) + if err != nil { + return err + } + } + + // Call API + req, _ := buildRequest(ctx, model, apiClient) + if err != nil { + return err + } + + keyVersion, err := req.Execute() + if err != nil { + return fmt.Errorf("import KMS Key: %w", err) + } + + // No wait exists for the wrapped key import + return outputResult(params.Printer, model.OutputFormat, keyRingName, keyName, keyVersion) + }, + } + configureFlags(cmd) + return cmd +} + +func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { + globalFlags := globalflags.Parse(p, cmd) + if globalFlags.ProjectId == "" { + return nil, &cliErr.ProjectIdError{} + } + + // What checks could this need? + // I would rather let the creation fail instead of checking all possible algorithms + model := inputModel{ + GlobalFlagModel: globalFlags, + KeyRingId: flags.FlagToStringValue(p, cmd, keyRingIdFlag), + KeyId: flags.FlagToStringValue(p, cmd, keyIdFlag), + WrappedKey: flags.FlagToStringPointer(p, cmd, wrappedKeyFlag), + WrappingKeyId: flags.FlagToStringPointer(p, cmd, wrappingKeyIdFlag), + } + + if p.IsVerbosityDebug() { + modelStr, err := print.BuildDebugStrFromInputModel(model) + if err != nil { + p.Debug(print.ErrorLevel, "convert model to string for debugging: %v", err) + } else { + p.Debug(print.ErrorLevel, "parsed input values: %s", modelStr) + } + } + + return &model, nil +} + +type kmsKeyClient interface { + ImportKey(ctx context.Context, projectId string, regionId string, keyRingId string, keyId string) kms.ApiImportKeyRequest +} + +func buildRequest(ctx context.Context, model *inputModel, apiClient kmsKeyClient) (kms.ApiImportKeyRequest, error) { + req := apiClient.ImportKey(ctx, model.ProjectId, model.Region, model.KeyRingId, model.KeyId) + + // Question: Should there be additional checks here? + req = req.ImportKeyPayload(kms.ImportKeyPayload{ + WrappedKey: model.WrappedKey, + WrappingKeyId: model.WrappingKeyId, + }) + return req, nil +} + +func outputResult(p *print.Printer, outputFormat, keyRingName, keyName string, resp *kms.Version) error { + if resp == nil { + return fmt.Errorf("response is nil") + } + + switch outputFormat { + case print.JSONOutputFormat: + details, err := json.MarshalIndent(resp, "", " ") + if err != nil { + return fmt.Errorf("marshal KMS Key: %w", err) + } + p.Outputln(string(details)) + return nil + + case print.YAMLOutputFormat: + details, err := yaml.MarshalWithOptions(resp, yaml.IndentSequence(true), yaml.UseJSONMarshaler()) + if err != nil { + return fmt.Errorf("marshal KMS Key: %w", err) + } + p.Outputln(string(details)) + return nil + + default: + p.Outputf("Imported a new version for the Key %q inside the Key Ring %q\n", keyName, keyRingName) + return nil + } +} + +func configureFlags(cmd *cobra.Command) { + cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS Key Ring") + cmd.Flags().Var(flags.UUIDFlag(), keyIdFlag, "ID of the KMS Key") + cmd.Flags().String(wrappedKeyFlag, "", "The wrapped key material that has to be imported. Encoded in base64") + cmd.Flags().Var(flags.UUIDFlag(), wrappingKeyIdFlag, "he unique id of the wrapping key the key material has been wrapped with") + + err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, keyIdFlag, wrappedKeyFlag, wrappingKeyIdFlag) + cobra.CheckErr(err) +} diff --git a/internal/cmd/beta/kms/key/key.go b/internal/cmd/beta/kms/key/key.go new file mode 100644 index 000000000..562207eca --- /dev/null +++ b/internal/cmd/beta/kms/key/key.go @@ -0,0 +1,36 @@ +package key + +import ( + "github.com/stackitcloud/stackit-cli/internal/cmd/beta/kms/key/create" + "github.com/stackitcloud/stackit-cli/internal/cmd/beta/kms/key/delete" + "github.com/stackitcloud/stackit-cli/internal/cmd/beta/kms/key/importKey" + "github.com/stackitcloud/stackit-cli/internal/cmd/beta/kms/key/list" + "github.com/stackitcloud/stackit-cli/internal/cmd/beta/kms/key/restore" + "github.com/stackitcloud/stackit-cli/internal/cmd/beta/kms/key/rotate" + "github.com/stackitcloud/stackit-cli/internal/cmd/params" + "github.com/stackitcloud/stackit-cli/internal/pkg/args" + "github.com/stackitcloud/stackit-cli/internal/pkg/utils" + + "github.com/spf13/cobra" +) + +func NewCmd(params *params.CmdParams) *cobra.Command { + cmd := &cobra.Command{ + Use: "key", + Short: "Manage KMS Keys", + Long: "Provides CRUD functionality for Key operations inside the KMS", + Args: args.NoArgs, + Run: utils.CmdHelp, + } + addSubcommands(cmd, params) + return cmd +} + +func addSubcommands(cmd *cobra.Command, params *params.CmdParams) { + cmd.AddCommand(create.NewCmd(params)) + cmd.AddCommand(delete.NewCmd(params)) + cmd.AddCommand(importKey.NewCmd(params)) + cmd.AddCommand(list.NewCmd(params)) + cmd.AddCommand(restore.NewCmd(params)) + cmd.AddCommand(rotate.NewCmd(params)) +} diff --git a/internal/cmd/beta/kms/key/list/list.go b/internal/cmd/beta/kms/key/list/list.go new file mode 100644 index 000000000..45f9f4925 --- /dev/null +++ b/internal/cmd/beta/kms/key/list/list.go @@ -0,0 +1,149 @@ +package list + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/goccy/go-yaml" + "github.com/spf13/cobra" + "github.com/stackitcloud/stackit-cli/internal/cmd/params" + "github.com/stackitcloud/stackit-cli/internal/pkg/args" + "github.com/stackitcloud/stackit-cli/internal/pkg/errors" + "github.com/stackitcloud/stackit-cli/internal/pkg/examples" + "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" + "github.com/stackitcloud/stackit-cli/internal/pkg/print" + "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/client" + "github.com/stackitcloud/stackit-cli/internal/pkg/tables" + "github.com/stackitcloud/stackit-cli/internal/pkg/utils" + "github.com/stackitcloud/stackit-sdk-go/services/kms" +) + +const ( + keyRingIdArg = "KEYRING_ID" +) + +type inputModel struct { + *globalflags.GlobalFlagModel + keyRingId string +} + +func NewCmd(params *params.CmdParams) *cobra.Command { + cmd := &cobra.Command{ + Use: fmt.Sprintf("list %s", keyRingIdArg), + Short: "Lists all KMS Keys", + Long: "Lists all KMS Keys inside a key ring.", + Args: args.SingleArg(keyRingIdArg, utils.ValidateUUID), + Example: examples.Build( + examples.NewExample( + `List all KMS Keys for the key ring "xxx"`, + "$ stackit beta kms key list xxx"), + examples.NewExample( + `List all KMS Keys in JSON format`, + "$ stackit beta kms key list xxx --output-format json"), + ), + RunE: func(cmd *cobra.Command, args []string) error { + ctx := context.Background() + model, err := parseInput(params.Printer, cmd, args) + if err != nil { + return err + } + + // Configure API client + apiClient, err := client.ConfigureClient(params.Printer, params.CliVersion) + if err != nil { + return err + } + + // Call API + req := buildRequest(ctx, model, apiClient) + resp, err := req.Execute() + if err != nil { + return fmt.Errorf("get KMS Keys: %w", err) + } + if resp.Keys == nil || len(*resp.Keys) == 0 { + params.Printer.Info("No Keys found for project %q in region %q under the key ring %q\n", model.ProjectId, model.Region, model.keyRingId) + return nil + } + keys := *resp.Keys + + return outputResult(params.Printer, model.OutputFormat, keys) + }, + } + + return cmd +} + +func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inputModel, error) { + keyRingId := inputArgs[0] + + globalFlags := globalflags.Parse(p, cmd) + if globalFlags.ProjectId == "" { + return nil, &errors.ProjectIdError{} + } + + model := inputModel{ + GlobalFlagModel: globalFlags, + keyRingId: keyRingId, + } + + if p.IsVerbosityDebug() { + modelStr, err := print.BuildDebugStrFromInputModel(model) + if err != nil { + p.Debug(print.ErrorLevel, "convert model to string for debugging: %v", err) + } else { + p.Debug(print.DebugLevel, "parsed input values: %s", modelStr) + } + } + + return &model, nil +} + +func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClient) kms.ApiListKeysRequest { + req := apiClient.ListKeys(ctx, model.ProjectId, model.Region, model.keyRingId) + return req +} + +func outputResult(p *print.Printer, outputFormat string, keys []kms.Key) error { + switch outputFormat { + case print.JSONOutputFormat: + details, err := json.MarshalIndent(keys, "", " ") + if err != nil { + return fmt.Errorf("marshal KMS Keys list: %w", err) + } + p.Outputln(string(details)) + + return nil + case print.YAMLOutputFormat: + details, err := yaml.MarshalWithOptions(keys, yaml.IndentSequence(true), yaml.UseJSONMarshaler()) + if err != nil { + return fmt.Errorf("marshal KMS Keys list: %w", err) + } + p.Outputln(string(details)) + + return nil + default: + table := tables.NewTable() + table.SetHeader("ID", "NAME", "SCOPE", "ALGORITHM", "DELETION DATE", "STATUS") + + for i := range keys { + key := keys[i] + table.AddRow( + utils.PtrString(key.Id), + utils.PtrString(key.DisplayName), + utils.PtrString(key.Purpose), + utils.PtrString(key.Algorithm), + // utils.PtrString(wrappingKeys.CreatedAt), + utils.PtrString(key.DeletionDate), + utils.PtrString(key.State), + ) + } + + err := table.Display(p) + if err != nil { + return fmt.Errorf("render table: %w", err) + } + + return nil + } +} diff --git a/internal/cmd/beta/kms/key/restore/restore.go b/internal/cmd/beta/kms/key/restore/restore.go new file mode 100644 index 000000000..1abcc22f1 --- /dev/null +++ b/internal/cmd/beta/kms/key/restore/restore.go @@ -0,0 +1,133 @@ +package restore + +import ( + "context" + "fmt" + + "github.com/spf13/cobra" + "github.com/stackitcloud/stackit-cli/internal/cmd/params" + "github.com/stackitcloud/stackit-cli/internal/pkg/args" + "github.com/stackitcloud/stackit-cli/internal/pkg/errors" + "github.com/stackitcloud/stackit-cli/internal/pkg/examples" + "github.com/stackitcloud/stackit-cli/internal/pkg/flags" + "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" + "github.com/stackitcloud/stackit-cli/internal/pkg/print" + kmsUtils "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/utils" + + "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/client" + "github.com/stackitcloud/stackit-cli/internal/pkg/utils" + "github.com/stackitcloud/stackit-sdk-go/services/kms" +) + +const ( + keyRingIdFlag = "key-ring" + keyIdFlag = "key" +) + +type inputModel struct { + *globalflags.GlobalFlagModel + KeyRingId string + KeyId string +} + +func NewCmd(params *params.CmdParams) *cobra.Command { + cmd := &cobra.Command{ + Use: "restore", + Short: "Resotre a Key", + Long: "Restores the given key from being deleted.", + Args: args.NoArgs, + Example: examples.Build( + examples.NewExample( + `Restore a KMS Key "my-key-id" inside the Key Ring "my-key-ring-id" that was scheduled for deletion.`, + `$ stackit beta kms keyring restore --key-ring "my-key-ring-id" --key "my-key-id"`), + ), + RunE: func(cmd *cobra.Command, _ []string) error { + ctx := context.Background() + model, err := parseInput(params.Printer, cmd) + if err != nil { + return err + } + + // Configure API client + apiClient, err := client.ConfigureClient(params.Printer, params.CliVersion) + if err != nil { + return err + } + + keyName, err := kmsUtils.GetKeyName(ctx, apiClient, model.ProjectId, model.Region, model.KeyRingId, model.KeyId) + if err != nil { + params.Printer.Debug(print.ErrorLevel, "get key name: %v", err) + keyName = model.KeyId + } + + if !model.AssumeYes { + prompt := fmt.Sprintf("Are you sure you want to restore key %q? (This cannot be undone)", keyName) + err = params.Printer.PromptForConfirmation(prompt) + if err != nil { + return err + } + } + + // Call API + req := buildRequest(ctx, model, apiClient) + err = req.Execute() + if err != nil { + return fmt.Errorf("restore KMS Key: %w", err) + } + + params.Printer.Info("Restored Key %q\n", keyName) + return nil + }, + } + + configureFlags(cmd) + return cmd +} + +func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { + globalFlags := globalflags.Parse(p, cmd) + if globalFlags.ProjectId == "" { + return nil, &errors.ProjectIdError{} + } + + keyRingId := flags.FlagToStringValue(p, cmd, keyRingIdFlag) + keyId := flags.FlagToStringValue(p, cmd, keyIdFlag) + + // Validate the uuid format of the IDs + errKeyRing := utils.ValidateUUID(keyRingId) + errKey := utils.ValidateUUID(keyId) + if errKeyRing != nil || errKey != nil { + return nil, &errors.DSAInputPlanError{ + Cmd: cmd, + } + } + + model := inputModel{ + GlobalFlagModel: globalFlags, + KeyRingId: keyRingId, + KeyId: keyId, + } + + if p.IsVerbosityDebug() { + modelStr, err := print.BuildDebugStrFromInputModel(model) + if err != nil { + p.Debug(print.ErrorLevel, "convert model to string for debugging: %v", err) + } else { + p.Debug(print.DebugLevel, "parsed input values: %s", modelStr) + } + } + + return &model, nil +} + +func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClient) kms.ApiRestoreKeyRequest { + req := apiClient.RestoreKey(ctx, model.ProjectId, model.Region, model.KeyRingId, model.KeyId) + return req +} + +func configureFlags(cmd *cobra.Command) { + cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS Key Ring where the Key is stored") + cmd.Flags().Var(flags.UUIDFlag(), keyIdFlag, "ID of the actual Key") + err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, keyIdFlag) + cobra.CheckErr(err) +} diff --git a/internal/cmd/beta/kms/key/rotate/rotate.go b/internal/cmd/beta/kms/key/rotate/rotate.go new file mode 100644 index 000000000..7ae32d03e --- /dev/null +++ b/internal/cmd/beta/kms/key/rotate/rotate.go @@ -0,0 +1,162 @@ +package rotate + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/goccy/go-yaml" + "github.com/spf13/cobra" + "github.com/stackitcloud/stackit-cli/internal/cmd/params" + "github.com/stackitcloud/stackit-cli/internal/pkg/args" + "github.com/stackitcloud/stackit-cli/internal/pkg/errors" + "github.com/stackitcloud/stackit-cli/internal/pkg/examples" + "github.com/stackitcloud/stackit-cli/internal/pkg/flags" + "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" + "github.com/stackitcloud/stackit-cli/internal/pkg/print" + kmsUtils "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/utils" + + "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/client" + "github.com/stackitcloud/stackit-cli/internal/pkg/utils" + "github.com/stackitcloud/stackit-sdk-go/services/kms" +) + +const ( + keyRingIdFlag = "key-ring" + keyIdFlag = "key" +) + +type inputModel struct { + *globalflags.GlobalFlagModel + KeyRingId string + KeyId string +} + +func NewCmd(params *params.CmdParams) *cobra.Command { + cmd := &cobra.Command{ + Use: "rotate", + Short: "Rotate a key", + Long: "Rotates the given key.", + Args: args.NoArgs, + Example: examples.Build( + examples.NewExample( + `Rotate a KMS Key "my-key-id" and increase it's version inside the Key Ring "my-key-ring-id".`, + `$ stackit beta kms keyring rotate --key-ring "my-key-ring-id" --key "my-key-id"`), + ), + RunE: func(cmd *cobra.Command, _ []string) error { + ctx := context.Background() + model, err := parseInput(params.Printer, cmd) + if err != nil { + return err + } + + // Configure API client + apiClient, err := client.ConfigureClient(params.Printer, params.CliVersion) + if err != nil { + return err + } + + keyName, err := kmsUtils.GetKeyName(ctx, apiClient, model.ProjectId, model.Region, model.KeyRingId, model.KeyId) + if err != nil { + params.Printer.Debug(print.ErrorLevel, "get key name: %v", err) + keyName = model.KeyId + } + + if !model.AssumeYes { + prompt := fmt.Sprintf("Are you sure you want to rotate the key %q? (This cannot be undone)", keyName) + err = params.Printer.PromptForConfirmation(prompt) + if err != nil { + return err + } + } + + // Call API + req := buildRequest(ctx, model, apiClient) + resp, err := req.Execute() + if err != nil { + return fmt.Errorf("rotate KMS Key: %w", err) + } + + return outputResult(params.Printer, model.OutputFormat, resp) + }, + } + + configureFlags(cmd) + return cmd +} + +func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { + globalFlags := globalflags.Parse(p, cmd) + if globalFlags.ProjectId == "" { + return nil, &errors.ProjectIdError{} + } + + keyRingId := flags.FlagToStringValue(p, cmd, keyRingIdFlag) + keyId := flags.FlagToStringValue(p, cmd, keyIdFlag) + + // Validate the uuid format of the IDs + errKeyRing := utils.ValidateUUID(keyRingId) + errKey := utils.ValidateUUID(keyId) + if errKeyRing != nil || errKey != nil { + return nil, &errors.DSAInputPlanError{ + Cmd: cmd, + } + } + + model := inputModel{ + GlobalFlagModel: globalFlags, + KeyRingId: keyRingId, + KeyId: keyId, + } + + if p.IsVerbosityDebug() { + modelStr, err := print.BuildDebugStrFromInputModel(model) + if err != nil { + p.Debug(print.ErrorLevel, "convert model to string for debugging: %v", err) + } else { + p.Debug(print.DebugLevel, "parsed input values: %s", modelStr) + } + } + + return &model, nil +} + +func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClient) kms.ApiRotateKeyRequest { + req := apiClient.RotateKey(ctx, model.ProjectId, model.Region, model.KeyRingId, model.KeyId) + return req +} + +func configureFlags(cmd *cobra.Command) { + cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS Key Ring where the Key is stored") + cmd.Flags().Var(flags.UUIDFlag(), keyIdFlag, "ID of the actual Key") + err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, keyIdFlag) + cobra.CheckErr(err) +} + +func outputResult(p *print.Printer, outputFormat string, resp *kms.Version) error { + if resp == nil { + return fmt.Errorf("response is nil") + } + + switch outputFormat { + case print.JSONOutputFormat: + details, err := json.MarshalIndent(resp, "", " ") + if err != nil { + return fmt.Errorf("marshal KMS Key Version: %w", err) + } + p.Outputln(string(details)) + return nil + + case print.YAMLOutputFormat: + details, err := yaml.MarshalWithOptions(resp, yaml.IndentSequence(true), yaml.UseJSONMarshaler()) + if err != nil { + return fmt.Errorf("marshal KMS Key Version: %w", err) + } + p.Outputln(string(details)) + return nil + + default: + p.Outputf("Rotated Key %s\n", utils.PtrString(resp.KeyId)) + return nil + } +} diff --git a/internal/cmd/beta/kms/keyring/create/create.go b/internal/cmd/beta/kms/keyring/create/create.go new file mode 100644 index 000000000..c12bcb423 --- /dev/null +++ b/internal/cmd/beta/kms/keyring/create/create.go @@ -0,0 +1,187 @@ +package create + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/goccy/go-yaml" + "github.com/spf13/cobra" + "github.com/stackitcloud/stackit-cli/internal/cmd/params" + "github.com/stackitcloud/stackit-cli/internal/pkg/args" + cliErr "github.com/stackitcloud/stackit-cli/internal/pkg/errors" + "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/client" + "github.com/stackitcloud/stackit-cli/internal/pkg/spinner" + + "github.com/stackitcloud/stackit-cli/internal/pkg/examples" + "github.com/stackitcloud/stackit-cli/internal/pkg/flags" + "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" + "github.com/stackitcloud/stackit-cli/internal/pkg/print" + "github.com/stackitcloud/stackit-cli/internal/pkg/projectname" + "github.com/stackitcloud/stackit-cli/internal/pkg/utils" + "github.com/stackitcloud/stackit-sdk-go/services/kms" + "github.com/stackitcloud/stackit-sdk-go/services/kms/wait" +) + +const ( + keyRingNameFlag = "name" + descriptionFlag = "description" +) + +type inputModel struct { + *globalflags.GlobalFlagModel + KeyringName string + Description string +} + +func NewCmd(params *params.CmdParams) *cobra.Command { + cmd := &cobra.Command{ + Use: "create", + Short: "Creates a KMS Key Ring", + Long: "Creates a KMS Key Ring.", + Args: args.NoArgs, + Example: examples.Build( + examples.NewExample( + `Create a KMS key ring`, + "$ stakit beta kms keyring create --name my-keyring"), + examples.NewExample( + `Create a KMS Key ring with a description`, + "$ stakit beta kms keyring create --name my-keyring --description my-description"), + ), + RunE: func(cmd *cobra.Command, _ []string) error { + ctx := context.Background() + model, err := parseInput(params.Printer, cmd) + if err != nil { + return err + } + + // Configure API client + apiClient, err := client.ConfigureClient(params.Printer, params.CliVersion) + if err != nil { + return err + } + + projectLabel, err := projectname.GetProjectName(ctx, params.Printer, params.CliVersion, cmd) + if err != nil { + params.Printer.Debug(print.ErrorLevel, "get project name: %v", err) + projectLabel = model.ProjectId + } + + if !model.AssumeYes { + prompt := fmt.Sprintf("Are you sure you want to create a KMS Key Ring for project %q?", projectLabel) + err = params.Printer.PromptForConfirmation(prompt) + if err != nil { + return err + } + } + + // Call API + req, _ := buildRequest(ctx, model, apiClient) + + keyRing, err := req.Execute() + if err != nil { + return fmt.Errorf("create KMS Key Ring: %w", err) + } + keyRingId := *keyRing.Id + + // Wait for async operation, if async mode not enabled + if !model.Async { + s := spinner.New(params.Printer) + s.Start("Creating instance") + _, err = wait.CreateKeyRingWaitHandler(ctx, apiClient, model.ProjectId, model.Region, keyRingId).WaitWithContext(ctx) + if err != nil { + return fmt.Errorf("wait for KMS Key Ring creation: %w", err) + } + s.Stop() + } + + return outputResult(params.Printer, model.OutputFormat, projectLabel, keyRing) + }, + } + configureFlags(cmd) + return cmd +} + +func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { + globalFlags := globalflags.Parse(p, cmd) + if globalFlags.ProjectId == "" { + return nil, &cliErr.ProjectIdError{} + } + + keyringName := flags.FlagToStringValue(p, cmd, keyRingNameFlag) + + if keyringName == "" { + return nil, &cliErr.DSAInputPlanError{ + Cmd: cmd, + } + } + + model := inputModel{ + GlobalFlagModel: globalFlags, + KeyringName: keyringName, + Description: flags.FlagToStringValue(p, cmd, descriptionFlag), + } + + if p.IsVerbosityDebug() { + modelStr, err := print.BuildDebugStrFromInputModel(model) + if err != nil { + p.Debug(print.ErrorLevel, "convert model to string for debugging: %v", err) + } else { + p.Debug(print.ErrorLevel, "parsed input values: %s", modelStr) + } + } + + return &model, nil +} + +type kmsKeyringClient interface { + CreateKeyRing(ctx context.Context, projectId string, regionId string) kms.ApiCreateKeyRingRequest +} + +func buildRequest(ctx context.Context, model *inputModel, apiClient kmsKeyringClient) (kms.ApiCreateKeyRingRequest, error) { + req := apiClient.CreateKeyRing(ctx, model.ProjectId, model.Region) + + req = req.CreateKeyRingPayload(kms.CreateKeyRingPayload{ + DisplayName: &model.KeyringName, + + // Description should be empty by default and only be overwritten with the descriptionFlag if it was passed. + Description: &model.Description, + }) + return req, nil +} + +func outputResult(p *print.Printer, outputFormat, projectLabel string, resp *kms.KeyRing) error { + if resp == nil { + return fmt.Errorf("response is nil") + } + + switch outputFormat { + case print.JSONOutputFormat: + details, err := json.MarshalIndent(resp, "", " ") + if err != nil { + return fmt.Errorf("marshal KMS Keyring: %w", err) + } + p.Outputln(string(details)) + return nil + + case print.YAMLOutputFormat: + details, err := yaml.MarshalWithOptions(resp, yaml.IndentSequence(true), yaml.UseJSONMarshaler()) + if err != nil { + return fmt.Errorf("marshal KMS Keyring: %w", err) + } + p.Outputln(string(details)) + return nil + + default: + p.Outputf("Created instance for project %q. Instance ID: %s\n", projectLabel, utils.PtrString(resp.Id)) + return nil + } +} + +func configureFlags(cmd *cobra.Command) { + cmd.Flags().String(keyRingNameFlag, "", "Name of the KMS Key Ring") + cmd.Flags().String(descriptionFlag, "", "Optinal description of the Key Ring") + + err := flags.MarkFlagsRequired(cmd, keyRingNameFlag) + cobra.CheckErr(err) +} diff --git a/internal/cmd/beta/kms/keyring/delete/delete.go b/internal/cmd/beta/kms/keyring/delete/delete.go new file mode 100644 index 000000000..e1d9d1c9a --- /dev/null +++ b/internal/cmd/beta/kms/keyring/delete/delete.go @@ -0,0 +1,112 @@ +package delete + +import ( + "context" + "fmt" + + "github.com/spf13/cobra" + "github.com/stackitcloud/stackit-cli/internal/cmd/params" + "github.com/stackitcloud/stackit-cli/internal/pkg/args" + "github.com/stackitcloud/stackit-cli/internal/pkg/errors" + "github.com/stackitcloud/stackit-cli/internal/pkg/examples" + "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" + "github.com/stackitcloud/stackit-cli/internal/pkg/print" + kmsUtils "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/utils" + + "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/client" + "github.com/stackitcloud/stackit-cli/internal/pkg/utils" + "github.com/stackitcloud/stackit-sdk-go/services/kms" +) + +const ( + keyRingIdArg = "KEYRING_ID" +) + +type inputModel struct { + *globalflags.GlobalFlagModel + keyRingId string +} + +func NewCmd(params *params.CmdParams) *cobra.Command { + cmd := &cobra.Command{ + Use: fmt.Sprintf("delete %s", keyRingIdArg), + Short: "Deletes a KMS Keyring", + Long: "Deletes a KMS Keyring.", + Args: args.SingleArg(keyRingIdArg, utils.ValidateUUID), + Example: examples.Build( + examples.NewExample( + `Delete a KMS Keyring with ID "xxx"`, + "$ stackit beta kms keyring delete xxx"), + ), + RunE: func(cmd *cobra.Command, args []string) error { + ctx := context.Background() + model, err := parseInput(params.Printer, cmd, args) + if err != nil { + return err + } + + // Configure API client + apiClient, err := client.ConfigureClient(params.Printer, params.CliVersion) + if err != nil { + return err + } + + keyRingLabel, err := kmsUtils.GetKeyRingName(ctx, apiClient, model.ProjectId, model.keyRingId, model.Region) + if err != nil { + params.Printer.Debug(print.ErrorLevel, "get key ring name: %v", err) + keyRingLabel = model.keyRingId + } + + if !model.AssumeYes { + prompt := fmt.Sprintf("Are you sure you want to delete key ring %q? (This cannot be undone)", keyRingLabel) + err = params.Printer.PromptForConfirmation(prompt) + if err != nil { + return err + } + } + + // Call API + req := buildRequest(ctx, model, apiClient) + err = req.Execute() + if err != nil { + return fmt.Errorf("delete KMS Key Ring: %w", err) + } + + // Wait for async operation not relevant. Keyring deletion is synchronous. + + params.Printer.Info("Deleted key ring %q\n", keyRingLabel) + return nil + }, + } + return cmd +} + +func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inputModel, error) { + keyRingId := inputArgs[0] + + globalFlags := globalflags.Parse(p, cmd) + if globalFlags.ProjectId == "" { + return nil, &errors.ProjectIdError{} + } + + model := inputModel{ + GlobalFlagModel: globalFlags, + keyRingId: keyRingId, + } + + if p.IsVerbosityDebug() { + modelStr, err := print.BuildDebugStrFromInputModel(model) + if err != nil { + p.Debug(print.ErrorLevel, "convert model to string for debugging: %v", err) + } else { + p.Debug(print.DebugLevel, "parsed input values: %s", modelStr) + } + } + + return &model, nil +} + +func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClient) kms.ApiDeleteKeyRingRequest { + req := apiClient.DeleteKeyRing(ctx, model.ProjectId, model.Region, model.keyRingId) + return req +} diff --git a/internal/cmd/beta/kms/keyring/keyring.go b/internal/cmd/beta/kms/keyring/keyring.go new file mode 100644 index 000000000..27c31f1e9 --- /dev/null +++ b/internal/cmd/beta/kms/keyring/keyring.go @@ -0,0 +1,30 @@ +package keyring + +import ( + "github.com/stackitcloud/stackit-cli/internal/cmd/beta/kms/keyring/create" + "github.com/stackitcloud/stackit-cli/internal/cmd/beta/kms/keyring/delete" + "github.com/stackitcloud/stackit-cli/internal/cmd/beta/kms/keyring/list" + "github.com/stackitcloud/stackit-cli/internal/cmd/params" + "github.com/stackitcloud/stackit-cli/internal/pkg/args" + "github.com/stackitcloud/stackit-cli/internal/pkg/utils" + + "github.com/spf13/cobra" +) + +func NewCmd(params *params.CmdParams) *cobra.Command { + cmd := &cobra.Command{ + Use: "keyring", + Short: "Manage KMS Keyrings", + Long: "Provides functionality for Keyring operations inside the KMS", + Args: args.NoArgs, + Run: utils.CmdHelp, + } + addSubcommands(cmd, params) + return cmd +} + +func addSubcommands(cmd *cobra.Command, params *params.CmdParams) { + cmd.AddCommand(list.NewCmd(params)) + cmd.AddCommand(delete.NewCmd(params)) + cmd.AddCommand(create.NewCmd(params)) +} diff --git a/internal/cmd/beta/kms/keyring/list/list.go b/internal/cmd/beta/kms/keyring/list/list.go new file mode 100644 index 000000000..e6cddeebf --- /dev/null +++ b/internal/cmd/beta/kms/keyring/list/list.go @@ -0,0 +1,138 @@ +package list + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/goccy/go-yaml" + "github.com/spf13/cobra" + "github.com/stackitcloud/stackit-cli/internal/cmd/params" + "github.com/stackitcloud/stackit-cli/internal/pkg/args" + "github.com/stackitcloud/stackit-cli/internal/pkg/errors" + "github.com/stackitcloud/stackit-cli/internal/pkg/examples" + "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" + "github.com/stackitcloud/stackit-cli/internal/pkg/print" + "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/client" + "github.com/stackitcloud/stackit-cli/internal/pkg/tables" + "github.com/stackitcloud/stackit-cli/internal/pkg/utils" + "github.com/stackitcloud/stackit-sdk-go/services/kms" +) + +type inputModel struct { + *globalflags.GlobalFlagModel +} + +func NewCmd(params *params.CmdParams) *cobra.Command { + cmd := &cobra.Command{ + Use: "list", + Short: "Lists all KMS Keyrings", + Long: "Lists all KMS Keyrings.", + Args: args.NoArgs, + Example: examples.Build( + // Enforce a specific region for the KMS + examples.NewExample( + `List all KMS Keyrings`, + "$ stackit beta kms keyring list"), + examples.NewExample( + `List all KMS Keyrings in JSON format`, + "$ stackit beta kms keyring list --output-format json"), + ), + RunE: func(cmd *cobra.Command, _ []string) error { + ctx := context.Background() + model, err := parseInput(params.Printer, cmd) + if err != nil { + return err + } + + // Configure API client + apiClient, err := client.ConfigureClient(params.Printer, params.CliVersion) + if err != nil { + return err + } + + // Call API + req := buildRequest(ctx, model, apiClient) + resp, err := req.Execute() + if err != nil { + return fmt.Errorf("get KMS Keyrings: %w", err) + } + if resp.KeyRings == nil || len(*resp.KeyRings) == 0 { + params.Printer.Info("No Keyrings found for project %q in region %q\n", model.ProjectId, model.Region) + return nil + } + keyRings := *resp.KeyRings + + return outputResult(params.Printer, model.OutputFormat, keyRings) + }, + } + + return cmd +} + +func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { + globalFlags := globalflags.Parse(p, cmd) + if globalFlags.ProjectId == "" { + return nil, &errors.ProjectIdError{} + } + + model := inputModel{ + GlobalFlagModel: globalFlags, + } + + if p.IsVerbosityDebug() { + modelStr, err := print.BuildDebugStrFromInputModel(model) + if err != nil { + p.Debug(print.ErrorLevel, "convert model to string for debugging: %v", err) + } else { + p.Debug(print.DebugLevel, "parsed input values: %s", modelStr) + } + } + + return &model, nil +} + +func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClient) kms.ApiListKeyRingsRequest { + req := apiClient.ListKeyRings(ctx, model.ProjectId, model.Region) + return req +} + +func outputResult(p *print.Printer, outputFormat string, keyRings []kms.KeyRing) error { + switch outputFormat { + case print.JSONOutputFormat: + details, err := json.MarshalIndent(keyRings, "", " ") + if err != nil { + return fmt.Errorf("marshal KMS Keyrings list: %w", err) + } + p.Outputln(string(details)) + + return nil + case print.YAMLOutputFormat: + details, err := yaml.MarshalWithOptions(keyRings, yaml.IndentSequence(true), yaml.UseJSONMarshaler()) + if err != nil { + return fmt.Errorf("marshal KMS Keyrings list: %w", err) + } + p.Outputln(string(details)) + + return nil + default: + table := tables.NewTable() + table.SetHeader("ID", "NAME", "STATUS") + + for i := range keyRings { + keyRing := keyRings[i] + table.AddRow( + utils.PtrString(keyRing.Id), + utils.PtrString(keyRing.DisplayName), + utils.PtrString(keyRing.State), + ) + } + + err := table.Display(p) + if err != nil { + return fmt.Errorf("render table: %w", err) + } + + return nil + } +} diff --git a/internal/cmd/beta/kms/kms.go b/internal/cmd/beta/kms/kms.go new file mode 100644 index 000000000..8eeb2b0d2 --- /dev/null +++ b/internal/cmd/beta/kms/kms.go @@ -0,0 +1,32 @@ +package kms + +import ( + "github.com/stackitcloud/stackit-cli/internal/cmd/beta/kms/key" + "github.com/stackitcloud/stackit-cli/internal/cmd/beta/kms/keyring" + "github.com/stackitcloud/stackit-cli/internal/cmd/beta/kms/version" + "github.com/stackitcloud/stackit-cli/internal/cmd/beta/kms/wrappingkey" + "github.com/stackitcloud/stackit-cli/internal/cmd/params" + "github.com/stackitcloud/stackit-cli/internal/pkg/args" + "github.com/stackitcloud/stackit-cli/internal/pkg/utils" + + "github.com/spf13/cobra" +) + +func NewCmd(params *params.CmdParams) *cobra.Command { + cmd := &cobra.Command{ + Use: "kms", + Short: "Provides functionality for KMS", + Long: "Provides functionality for KMS.", + Args: args.NoArgs, + Run: utils.CmdHelp, + } + addSubcommands(cmd, params) + return cmd +} + +func addSubcommands(cmd *cobra.Command, params *params.CmdParams) { + cmd.AddCommand(keyring.NewCmd(params)) + cmd.AddCommand(wrappingkey.NewCmd(params)) + cmd.AddCommand(key.NewCmd(params)) + cmd.AddCommand(version.NewCmd(params)) +} diff --git a/internal/cmd/beta/kms/version/destroy/destroy.go b/internal/cmd/beta/kms/version/destroy/destroy.go new file mode 100644 index 000000000..42811b276 --- /dev/null +++ b/internal/cmd/beta/kms/version/destroy/destroy.go @@ -0,0 +1,116 @@ +package destroy + +import ( + "context" + "fmt" + + "github.com/spf13/cobra" + "github.com/stackitcloud/stackit-cli/internal/cmd/params" + "github.com/stackitcloud/stackit-cli/internal/pkg/args" + "github.com/stackitcloud/stackit-cli/internal/pkg/errors" + "github.com/stackitcloud/stackit-cli/internal/pkg/examples" + "github.com/stackitcloud/stackit-cli/internal/pkg/flags" + "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" + "github.com/stackitcloud/stackit-cli/internal/pkg/print" + "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/client" + kmsUtils "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/utils" + "github.com/stackitcloud/stackit-sdk-go/services/kms" +) + +const ( + keyRingIdFlag = "key-ring" + keyIdFlag = "key" + versionNumberFlag = "version" +) + +type inputModel struct { + *globalflags.GlobalFlagModel + KeyRingId string + KeyId string + VersionNumber *int64 +} + +func NewCmd(params *params.CmdParams) *cobra.Command { + cmd := &cobra.Command{ + Use: "destroy", + Short: "Destroy a Key Versions", + Long: "Removes the key material of a version.", + Args: args.NoArgs, + Example: examples.Build( + examples.NewExample( + `Destroy key version "0" for the key "my-key-id" inside the key ring "my-key-ring-id"`, + `$ stackit beta kms version destroy --key "my-key-id" --key-ring "my-key-ring-id" --version 0`), + ), + RunE: func(cmd *cobra.Command, _ []string) error { + ctx := context.Background() + model, err := parseInput(params.Printer, cmd) + if err != nil { + return err + } + + // Configure API client + apiClient, err := client.ConfigureClient(params.Printer, params.CliVersion) + if err != nil { + return err + } + + keyName, err := kmsUtils.GetKeyName(ctx, apiClient, model.ProjectId, model.Region, model.KeyRingId, model.KeyId) + if err != nil { + params.Printer.Debug(print.ErrorLevel, "get key name: %v", err) + keyName = model.KeyId + } + // This operatio can be undone. Don't ask for confirmation! + + // Call API + req := buildRequest(ctx, model, apiClient) + err = req.Execute() + if err != nil { + return fmt.Errorf("destroy Key Version: %w", err) + } + + params.Printer.Info("Destroyed version %d of Key %q\n", *model.VersionNumber, keyName) + return nil + }, + } + + configureFlags(cmd) + return cmd +} + +func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { + globalFlags := globalflags.Parse(p, cmd) + if globalFlags.ProjectId == "" { + return nil, &errors.ProjectIdError{} + } + + model := inputModel{ + GlobalFlagModel: globalFlags, + KeyRingId: flags.FlagToStringValue(p, cmd, keyRingIdFlag), + KeyId: flags.FlagToStringValue(p, cmd, keyIdFlag), + VersionNumber: flags.FlagToInt64Pointer(p, cmd, versionNumberFlag), + } + + if p.IsVerbosityDebug() { + modelStr, err := print.BuildDebugStrFromInputModel(model) + if err != nil { + p.Debug(print.ErrorLevel, "convert model to string for debugging: %v", err) + } else { + p.Debug(print.DebugLevel, "parsed input values: %s", modelStr) + } + } + + return &model, nil +} + +func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClient) kms.ApiDestroyVersionRequest { + return apiClient.DestroyVersion(ctx, model.ProjectId, model.Region, model.KeyRingId, model.KeyId, *model.VersionNumber) +} + +func configureFlags(cmd *cobra.Command) { + cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS Key Ring") + cmd.Flags().Var(flags.UUIDFlag(), keyIdFlag, "ID of the Key") + cmd.Flags().Int64(versionNumberFlag, 0, "Version number of the key") + + err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, keyIdFlag, versionNumberFlag) + cobra.CheckErr(err) +} diff --git a/internal/cmd/beta/kms/version/disable/disable.go b/internal/cmd/beta/kms/version/disable/disable.go new file mode 100644 index 000000000..6eee81fa3 --- /dev/null +++ b/internal/cmd/beta/kms/version/disable/disable.go @@ -0,0 +1,130 @@ +package disable + +import ( + "context" + "fmt" + + "github.com/spf13/cobra" + "github.com/stackitcloud/stackit-cli/internal/cmd/params" + "github.com/stackitcloud/stackit-cli/internal/pkg/args" + "github.com/stackitcloud/stackit-cli/internal/pkg/errors" + "github.com/stackitcloud/stackit-cli/internal/pkg/examples" + "github.com/stackitcloud/stackit-cli/internal/pkg/flags" + "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" + "github.com/stackitcloud/stackit-cli/internal/pkg/print" + "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/client" + kmsUtils "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/utils" + "github.com/stackitcloud/stackit-cli/internal/pkg/spinner" + "github.com/stackitcloud/stackit-sdk-go/services/kms" + "github.com/stackitcloud/stackit-sdk-go/services/kms/wait" +) + +const ( + keyRingIdFlag = "key-ring" + keyIdFlag = "key" + versionNumberFlag = "version" +) + +type inputModel struct { + *globalflags.GlobalFlagModel + KeyRingId string + KeyId string + VersionNumber *int64 +} + +func NewCmd(params *params.CmdParams) *cobra.Command { + cmd := &cobra.Command{ + Use: "disable", + Short: "Disable a Key Versions", + Long: "Disable the given key version.", + Args: args.NoArgs, + Example: examples.Build( + examples.NewExample( + `Disable key version "0" for the key "my-key-id" inside the key ring "my-key-ring-id"`, + `$ stackit beta kms version disable --key "my-key-id" --key-ring "my-key-ring-id" --version 0`), + ), + RunE: func(cmd *cobra.Command, _ []string) error { + ctx := context.Background() + model, err := parseInput(params.Printer, cmd) + if err != nil { + return err + } + + // Configure API client + apiClient, err := client.ConfigureClient(params.Printer, params.CliVersion) + if err != nil { + return err + } + + keyName, err := kmsUtils.GetKeyName(ctx, apiClient, model.ProjectId, model.Region, model.KeyRingId, model.KeyId) + if err != nil { + params.Printer.Debug(print.ErrorLevel, "get key name: %v", err) + keyName = model.KeyId + } + + // This operatio can be undone. Don't ask for confirmation! + + // Call API + req := buildRequest(ctx, model, apiClient) + err = req.Execute() + if err != nil { + return fmt.Errorf("disable Key Version: %w", err) + } + + // Wait for async operation, if async mode not enabled + if !model.Async { + s := spinner.New(params.Printer) + s.Start("Disableing key version") + _, err = wait.DisableKeyVersionWaitHandler(ctx, apiClient, model.ProjectId, model.Region, model.KeyRingId, model.KeyId, *model.VersionNumber).WaitWithContext(ctx) + if err != nil { + return fmt.Errorf("wait for Key Version to be disabled: %w", err) + } + s.Stop() + } + + params.Printer.Info("Disabled version %d of Key %q\n", *model.VersionNumber, keyName) + return nil + }, + } + + configureFlags(cmd) + return cmd +} + +func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { + globalFlags := globalflags.Parse(p, cmd) + if globalFlags.ProjectId == "" { + return nil, &errors.ProjectIdError{} + } + + model := inputModel{ + GlobalFlagModel: globalFlags, + KeyRingId: flags.FlagToStringValue(p, cmd, keyRingIdFlag), + KeyId: flags.FlagToStringValue(p, cmd, keyIdFlag), + VersionNumber: flags.FlagToInt64Pointer(p, cmd, versionNumberFlag), + } + + if p.IsVerbosityDebug() { + modelStr, err := print.BuildDebugStrFromInputModel(model) + if err != nil { + p.Debug(print.ErrorLevel, "convert model to string for debugging: %v", err) + } else { + p.Debug(print.DebugLevel, "parsed input values: %s", modelStr) + } + } + + return &model, nil +} + +func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClient) kms.ApiDisableVersionRequest { + return apiClient.DisableVersion(ctx, model.ProjectId, model.Region, model.KeyRingId, model.KeyId, *model.VersionNumber) +} + +func configureFlags(cmd *cobra.Command) { + cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS Key Ring") + cmd.Flags().Var(flags.UUIDFlag(), keyIdFlag, "ID of the Key") + cmd.Flags().Int64(versionNumberFlag, 0, "Version number of the key") + + err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, keyIdFlag, versionNumberFlag) + cobra.CheckErr(err) +} diff --git a/internal/cmd/beta/kms/version/enable/enable.go b/internal/cmd/beta/kms/version/enable/enable.go new file mode 100644 index 000000000..4aa52bac7 --- /dev/null +++ b/internal/cmd/beta/kms/version/enable/enable.go @@ -0,0 +1,130 @@ +package enable + +import ( + "context" + "fmt" + + "github.com/spf13/cobra" + "github.com/stackitcloud/stackit-cli/internal/cmd/params" + "github.com/stackitcloud/stackit-cli/internal/pkg/args" + "github.com/stackitcloud/stackit-cli/internal/pkg/errors" + "github.com/stackitcloud/stackit-cli/internal/pkg/examples" + "github.com/stackitcloud/stackit-cli/internal/pkg/flags" + "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" + "github.com/stackitcloud/stackit-cli/internal/pkg/print" + "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/client" + kmsUtils "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/utils" + "github.com/stackitcloud/stackit-cli/internal/pkg/spinner" + "github.com/stackitcloud/stackit-sdk-go/services/kms" + "github.com/stackitcloud/stackit-sdk-go/services/kms/wait" +) + +const ( + keyRingIdFlag = "key-ring" + keyIdFlag = "key" + versionNumberFlag = "version" +) + +type inputModel struct { + *globalflags.GlobalFlagModel + KeyRingId string + KeyId string + VersionNumber *int64 +} + +func NewCmd(params *params.CmdParams) *cobra.Command { + cmd := &cobra.Command{ + Use: "enable", + Short: "Enable a Key Versions", + Long: "Enable the given key version.", + Args: args.NoArgs, + Example: examples.Build( + examples.NewExample( + `Enable key version "0" for the key "my-key-id" inside the key ring "my-key-ring-id"`, + `$ stackit beta kms version enable --key "my-key-id" --key-ring "my-key-ring-id" --version 0`), + ), + RunE: func(cmd *cobra.Command, _ []string) error { + ctx := context.Background() + model, err := parseInput(params.Printer, cmd) + if err != nil { + return err + } + + // Configure API client + apiClient, err := client.ConfigureClient(params.Printer, params.CliVersion) + if err != nil { + return err + } + + keyName, err := kmsUtils.GetKeyName(ctx, apiClient, model.ProjectId, model.Region, model.KeyRingId, model.KeyId) + if err != nil { + params.Printer.Debug(print.ErrorLevel, "get key name: %v", err) + keyName = model.KeyId + } + + // This operatio can be undone. Don't ask for confirmation! + + // Call API + req := buildRequest(ctx, model, apiClient) + err = req.Execute() + if err != nil { + return fmt.Errorf("enable Key Version: %w", err) + } + + // Wait for async operation, if async mode not enabled + if !model.Async { + s := spinner.New(params.Printer) + s.Start("Enabling key version") + _, err = wait.EnableKeyVersionWaitHandler(ctx, apiClient, model.ProjectId, model.Region, model.KeyRingId, model.KeyId, *model.VersionNumber).WaitWithContext(ctx) + if err != nil { + return fmt.Errorf("wait for Key Version to be enabled: %w", err) + } + s.Stop() + } + + params.Printer.Info("Enabled version %d of Key %q\n", *model.VersionNumber, keyName) + return nil + }, + } + + configureFlags(cmd) + return cmd +} + +func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { + globalFlags := globalflags.Parse(p, cmd) + if globalFlags.ProjectId == "" { + return nil, &errors.ProjectIdError{} + } + + model := inputModel{ + GlobalFlagModel: globalFlags, + KeyRingId: flags.FlagToStringValue(p, cmd, keyRingIdFlag), + KeyId: flags.FlagToStringValue(p, cmd, keyIdFlag), + VersionNumber: flags.FlagToInt64Pointer(p, cmd, versionNumberFlag), + } + + if p.IsVerbosityDebug() { + modelStr, err := print.BuildDebugStrFromInputModel(model) + if err != nil { + p.Debug(print.ErrorLevel, "convert model to string for debugging: %v", err) + } else { + p.Debug(print.DebugLevel, "parsed input values: %s", modelStr) + } + } + + return &model, nil +} + +func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClient) kms.ApiEnableVersionRequest { + return apiClient.EnableVersion(ctx, model.ProjectId, model.Region, model.KeyRingId, model.KeyId, *model.VersionNumber) +} + +func configureFlags(cmd *cobra.Command) { + cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS Key Ring") + cmd.Flags().Var(flags.UUIDFlag(), keyIdFlag, "ID of the Key") + cmd.Flags().Int64(versionNumberFlag, 0, "Version number of the key") + + err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, keyIdFlag, versionNumberFlag) + cobra.CheckErr(err) +} diff --git a/internal/cmd/beta/kms/version/list/list.go b/internal/cmd/beta/kms/version/list/list.go new file mode 100644 index 000000000..806da6b8d --- /dev/null +++ b/internal/cmd/beta/kms/version/list/list.go @@ -0,0 +1,157 @@ +package list + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/goccy/go-yaml" + "github.com/spf13/cobra" + "github.com/stackitcloud/stackit-cli/internal/cmd/params" + "github.com/stackitcloud/stackit-cli/internal/pkg/args" + "github.com/stackitcloud/stackit-cli/internal/pkg/errors" + "github.com/stackitcloud/stackit-cli/internal/pkg/examples" + "github.com/stackitcloud/stackit-cli/internal/pkg/flags" + "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" + "github.com/stackitcloud/stackit-cli/internal/pkg/print" + "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/client" + "github.com/stackitcloud/stackit-cli/internal/pkg/tables" + "github.com/stackitcloud/stackit-cli/internal/pkg/utils" + "github.com/stackitcloud/stackit-sdk-go/services/kms" +) + +const ( + keyRingIdFlag = "key-ring" + keyIdFlag = "key" +) + +type inputModel struct { + *globalflags.GlobalFlagModel + KeyRingId string + KeyId string +} + +func NewCmd(params *params.CmdParams) *cobra.Command { + cmd := &cobra.Command{ + Use: "list", + Short: "Lists all Key Versions", + Long: "Lists all versions of a given key.", + Args: args.NoArgs, + Example: examples.Build( + examples.NewExample( + `List all key versions for the key "my-key-id" inside the key ring "my-key-ring-id"`, + `$ stackit beta kms version list --key "my-key-id" --key-ring "my-key-ring-id"`), + examples.NewExample( + `List all key versions in JSON format`, + `$ stackit beta kms version list --key "my-key-id" --key-ring "my-key-ring-id" -o json`), + ), + RunE: func(cmd *cobra.Command, _ []string) error { + ctx := context.Background() + model, err := parseInput(params.Printer, cmd) + if err != nil { + return err + } + + // Configure API client + apiClient, err := client.ConfigureClient(params.Printer, params.CliVersion) + if err != nil { + return err + } + + // Call API + req := buildRequest(ctx, model, apiClient) + resp, err := req.Execute() + if err != nil { + return fmt.Errorf("get Key Versions: %w", err) + } + if resp.Versions == nil || len(*resp.Versions) == 0 { + params.Printer.Info("No Key Versions found for project %q in region %q for the key %q\n", model.ProjectId, model.Region, model.KeyId) + return nil + } + keys := *resp.Versions + + return outputResult(params.Printer, model.OutputFormat, keys) + }, + } + + configureFlags(cmd) + return cmd +} + +func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { + globalFlags := globalflags.Parse(p, cmd) + if globalFlags.ProjectId == "" { + return nil, &errors.ProjectIdError{} + } + + model := inputModel{ + GlobalFlagModel: globalFlags, + KeyRingId: flags.FlagToStringValue(p, cmd, keyRingIdFlag), + KeyId: flags.FlagToStringValue(p, cmd, keyIdFlag), + } + + if p.IsVerbosityDebug() { + modelStr, err := print.BuildDebugStrFromInputModel(model) + if err != nil { + p.Debug(print.ErrorLevel, "convert model to string for debugging: %v", err) + } else { + p.Debug(print.DebugLevel, "parsed input values: %s", modelStr) + } + } + + return &model, nil +} + +func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClient) kms.ApiListVersionsRequest { + return apiClient.ListVersions(ctx, model.ProjectId, model.Region, model.KeyRingId, model.KeyId) +} + +func outputResult(p *print.Printer, outputFormat string, versions []kms.Version) error { + switch outputFormat { + case print.JSONOutputFormat: + details, err := json.MarshalIndent(versions, "", " ") + if err != nil { + return fmt.Errorf("marshal Key Versions list: %w", err) + } + p.Outputln(string(details)) + + return nil + case print.YAMLOutputFormat: + details, err := yaml.MarshalWithOptions(versions, yaml.IndentSequence(true), yaml.UseJSONMarshaler()) + if err != nil { + return fmt.Errorf("marshal Key Versions list: %w", err) + } + p.Outputln(string(details)) + + return nil + default: + table := tables.NewTable() + table.SetHeader("ID", "NUMBER", "CREATED AT", "DESTROY DATE", "STATUS") + + for i := range versions { + version := versions[i] + table.AddRow( + utils.PtrString(version.KeyId), + utils.PtrString(version.Number), + utils.PtrString(version.CreatedAt), + utils.PtrString(version.DestroyDate), + utils.PtrString(version.State), + ) + } + + err := table.Display(p) + if err != nil { + return fmt.Errorf("render table: %w", err) + } + + return nil + } +} + +func configureFlags(cmd *cobra.Command) { + cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS Key Ring") + cmd.Flags().Var(flags.UUIDFlag(), keyIdFlag, "ID of the Key") + + err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, keyIdFlag) + cobra.CheckErr(err) +} diff --git a/internal/cmd/beta/kms/version/restore/restore.go b/internal/cmd/beta/kms/version/restore/restore.go new file mode 100644 index 000000000..c059391b9 --- /dev/null +++ b/internal/cmd/beta/kms/version/restore/restore.go @@ -0,0 +1,117 @@ +package restore + +import ( + "context" + "fmt" + + "github.com/spf13/cobra" + "github.com/stackitcloud/stackit-cli/internal/cmd/params" + "github.com/stackitcloud/stackit-cli/internal/pkg/args" + "github.com/stackitcloud/stackit-cli/internal/pkg/errors" + "github.com/stackitcloud/stackit-cli/internal/pkg/examples" + "github.com/stackitcloud/stackit-cli/internal/pkg/flags" + "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" + "github.com/stackitcloud/stackit-cli/internal/pkg/print" + "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/client" + kmsUtils "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/utils" + "github.com/stackitcloud/stackit-sdk-go/services/kms" +) + +const ( + keyRingIdFlag = "key-ring" + keyIdFlag = "key" + versionNumberFlag = "version" +) + +type inputModel struct { + *globalflags.GlobalFlagModel + KeyRingId string + KeyId string + VersionNumber *int64 +} + +func NewCmd(params *params.CmdParams) *cobra.Command { + cmd := &cobra.Command{ + Use: "restore", + Short: "Restore a Key Versions", + Long: "Restores the specified version of key.", + Args: args.NoArgs, + Example: examples.Build( + examples.NewExample( + `Restore key version "0" for the key "my-key-id" inside the key ring "my-key-ring-id"`, + `$ stackit beta kms version restore --key "my-key-id" --key-ring "my-key-ring-id" --version 0`), + ), + RunE: func(cmd *cobra.Command, _ []string) error { + ctx := context.Background() + model, err := parseInput(params.Printer, cmd) + if err != nil { + return err + } + + // Configure API client + apiClient, err := client.ConfigureClient(params.Printer, params.CliVersion) + if err != nil { + return err + } + + keyName, err := kmsUtils.GetKeyName(ctx, apiClient, model.ProjectId, model.Region, model.KeyRingId, model.KeyId) + if err != nil { + params.Printer.Debug(print.ErrorLevel, "get key name: %v", err) + keyName = model.KeyId + } + + // This operatio can be undone. Don't ask for confirmation! + + // Call API + req := buildRequest(ctx, model, apiClient) + err = req.Execute() + if err != nil { + return fmt.Errorf("restore Key Version: %w", err) + } + + params.Printer.Info("Restored version %d of Key %q\n", *model.VersionNumber, keyName) + return nil + }, + } + + configureFlags(cmd) + return cmd +} + +func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { + globalFlags := globalflags.Parse(p, cmd) + if globalFlags.ProjectId == "" { + return nil, &errors.ProjectIdError{} + } + + model := inputModel{ + GlobalFlagModel: globalFlags, + KeyRingId: flags.FlagToStringValue(p, cmd, keyRingIdFlag), + KeyId: flags.FlagToStringValue(p, cmd, keyIdFlag), + VersionNumber: flags.FlagToInt64Pointer(p, cmd, versionNumberFlag), + } + + if p.IsVerbosityDebug() { + modelStr, err := print.BuildDebugStrFromInputModel(model) + if err != nil { + p.Debug(print.ErrorLevel, "convert model to string for debugging: %v", err) + } else { + p.Debug(print.DebugLevel, "parsed input values: %s", modelStr) + } + } + + return &model, nil +} + +func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClient) kms.ApiRestoreVersionRequest { + return apiClient.RestoreVersion(ctx, model.ProjectId, model.Region, model.KeyRingId, model.KeyId, *model.VersionNumber) +} + +func configureFlags(cmd *cobra.Command) { + cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS Key Ring") + cmd.Flags().Var(flags.UUIDFlag(), keyIdFlag, "ID of the Key") + cmd.Flags().Int64(versionNumberFlag, 0, "Version number of the key") + + err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, keyIdFlag, versionNumberFlag) + cobra.CheckErr(err) +} diff --git a/internal/cmd/beta/kms/version/version.go b/internal/cmd/beta/kms/version/version.go new file mode 100644 index 000000000..47271fcd3 --- /dev/null +++ b/internal/cmd/beta/kms/version/version.go @@ -0,0 +1,34 @@ +package version + +import ( + "github.com/stackitcloud/stackit-cli/internal/cmd/beta/kms/version/destroy" + "github.com/stackitcloud/stackit-cli/internal/cmd/beta/kms/version/disable" + "github.com/stackitcloud/stackit-cli/internal/cmd/beta/kms/version/enable" + "github.com/stackitcloud/stackit-cli/internal/cmd/beta/kms/version/list" + "github.com/stackitcloud/stackit-cli/internal/cmd/beta/kms/version/restore" + "github.com/stackitcloud/stackit-cli/internal/cmd/params" + "github.com/stackitcloud/stackit-cli/internal/pkg/args" + "github.com/stackitcloud/stackit-cli/internal/pkg/utils" + + "github.com/spf13/cobra" +) + +func NewCmd(params *params.CmdParams) *cobra.Command { + cmd := &cobra.Command{ + Use: "version", + Short: "Manage KMS Key versions", + Long: "Provides CRUD functionality for Key Version operations inside the KMS", + Args: args.NoArgs, + Run: utils.CmdHelp, + } + addSubcommands(cmd, params) + return cmd +} + +func addSubcommands(cmd *cobra.Command, params *params.CmdParams) { + cmd.AddCommand(destroy.NewCmd(params)) + cmd.AddCommand(disable.NewCmd(params)) + cmd.AddCommand(enable.NewCmd(params)) + cmd.AddCommand(list.NewCmd(params)) + cmd.AddCommand(restore.NewCmd(params)) +} diff --git a/internal/cmd/beta/kms/wrappingkey/create/create.go b/internal/cmd/beta/kms/wrappingkey/create/create.go new file mode 100644 index 000000000..e10ba647a --- /dev/null +++ b/internal/cmd/beta/kms/wrappingkey/create/create.go @@ -0,0 +1,203 @@ +package create + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/goccy/go-yaml" + "github.com/spf13/cobra" + "github.com/stackitcloud/stackit-cli/internal/cmd/params" + "github.com/stackitcloud/stackit-cli/internal/pkg/args" + cliErr "github.com/stackitcloud/stackit-cli/internal/pkg/errors" + "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/client" + "github.com/stackitcloud/stackit-cli/internal/pkg/spinner" + + "github.com/stackitcloud/stackit-cli/internal/pkg/examples" + "github.com/stackitcloud/stackit-cli/internal/pkg/flags" + "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" + "github.com/stackitcloud/stackit-cli/internal/pkg/print" + "github.com/stackitcloud/stackit-cli/internal/pkg/projectname" + "github.com/stackitcloud/stackit-cli/internal/pkg/utils" + "github.com/stackitcloud/stackit-sdk-go/services/kms" + "github.com/stackitcloud/stackit-sdk-go/services/kms/wait" +) + +const ( + keyRingIdFlag = "key-ring" + + algorithmFlag = "algorithm" + backendFlag = "backend" + descriptionFlag = "description" + displayNameFlag = "name" + purposeFlag = "purpose" +) + +type inputModel struct { + *globalflags.GlobalFlagModel + KeyRingId string + + Algorithm *string + Backend string // Keep "backend" as a variable, but set the default to "software" (see UI) + Description *string + Name *string + Purpose *string +} + +func NewCmd(params *params.CmdParams) *cobra.Command { + cmd := &cobra.Command{ + Use: "create", + Short: "Creates a KMS Wrapping Key", + Long: "Creates a KMS Wrapping Key.", + Args: args.NoArgs, + Example: examples.Build( + examples.NewExample( + `Create a Symmetric KMS Wrapping Key`, + `$ stakit beta kms wrappingkey create --key-ring "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-wrapping-key-name" --purpose "wrap_symmetric_key"`), + examples.NewExample( + `Create an Asymmetric KMS Wrapping Key with a description`, + `$ stakit beta kms wrappingkey create --key-ring "my-keyring-id" --algorithm "hmac_sha256" --name "my-wrapping-key-name" --description "my-description" --purpose "wrap_asymmetric_key"`), + ), + RunE: func(cmd *cobra.Command, _ []string) error { + ctx := context.Background() + model, err := parseInput(params.Printer, cmd) + if err != nil { + return err + } + + // Configure API client + apiClient, err := client.ConfigureClient(params.Printer, params.CliVersion) + if err != nil { + return err + } + + projectLabel, err := projectname.GetProjectName(ctx, params.Printer, params.CliVersion, cmd) + if err != nil { + params.Printer.Debug(print.ErrorLevel, "get project name: %v", err) + projectLabel = model.ProjectId + } + + if !model.AssumeYes { + prompt := fmt.Sprintf("Are you sure you want to create a KMS Wrapping Key for project %q?", projectLabel) + err = params.Printer.PromptForConfirmation(prompt) + if err != nil { + return err + } + } + + // Call API + req, _ := buildRequest(ctx, model, apiClient) + if err != nil { + return err + } + + wrappingKey, err := req.Execute() + if err != nil { + return fmt.Errorf("create KMS Wrapping Key: %w", err) + } + + // Wait for async operation, if async mode not enabled + if !model.Async { + s := spinner.New(params.Printer) + s.Start("Creating instance") + _, err = wait.CreateWrappingKeyWaitHandler(ctx, apiClient, model.ProjectId, model.Region, *wrappingKey.KeyRingId, *wrappingKey.Id).WaitWithContext(ctx) + if err != nil { + return fmt.Errorf("wait for KMS Wrapping Key creation: %w", err) + } + s.Stop() + } + + return outputResult(params.Printer, model.OutputFormat, projectLabel, wrappingKey) + }, + } + configureFlags(cmd) + return cmd +} + +func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { + globalFlags := globalflags.Parse(p, cmd) + if globalFlags.ProjectId == "" { + return nil, &cliErr.ProjectIdError{} + } + + // All values are mandatory strings. No additional type check required. + model := inputModel{ + GlobalFlagModel: globalFlags, + KeyRingId: flags.FlagToStringValue(p, cmd, keyRingIdFlag), + Algorithm: flags.FlagToStringPointer(p, cmd, algorithmFlag), + Backend: flags.FlagWithDefaultToStringValue(p, cmd, backendFlag), + Name: flags.FlagToStringPointer(p, cmd, displayNameFlag), + Description: flags.FlagToStringPointer(p, cmd, descriptionFlag), + Purpose: flags.FlagToStringPointer(p, cmd, purposeFlag), + } + + if p.IsVerbosityDebug() { + modelStr, err := print.BuildDebugStrFromInputModel(model) + if err != nil { + p.Debug(print.ErrorLevel, "convert model to string for debugging: %v", err) + } else { + p.Debug(print.ErrorLevel, "parsed input values: %s", modelStr) + } + } + + return &model, nil +} + +type kmsWrappingKeyClient interface { + CreateWrappingKey(ctx context.Context, projectId string, regionId string, keyRingId string) kms.ApiCreateWrappingKeyRequest +} + +func buildRequest(ctx context.Context, model *inputModel, apiClient kmsWrappingKeyClient) (kms.ApiCreateWrappingKeyRequest, error) { + req := apiClient.CreateWrappingKey(ctx, model.ProjectId, model.Region, model.KeyRingId) + + // Question: Should there be additional checks here? + + req = req.CreateWrappingKeyPayload(kms.CreateWrappingKeyPayload{ + DisplayName: model.Name, + Description: model.Description, + Algorithm: kms.CreateWrappingKeyPayloadGetAlgorithmAttributeType(model.Algorithm), + Purpose: kms.CreateWrappingKeyPayloadGetPurposeAttributeType(model.Purpose), + Backend: kms.CreateWrappingKeyPayloadGetBackendAttributeType(&model.Backend), + }) + return req, nil +} + +func outputResult(p *print.Printer, outputFormat, projectLabel string, resp *kms.WrappingKey) error { + if resp == nil { + return fmt.Errorf("response is nil") + } + + switch outputFormat { + case print.JSONOutputFormat: + details, err := json.MarshalIndent(resp, "", " ") + if err != nil { + return fmt.Errorf("marshal KMS Wrapping Key: %w", err) + } + p.Outputln(string(details)) + return nil + + case print.YAMLOutputFormat: + details, err := yaml.MarshalWithOptions(resp, yaml.IndentSequence(true), yaml.UseJSONMarshaler()) + if err != nil { + return fmt.Errorf("marshal KMS Wrapping Key: %w", err) + } + p.Outputln(string(details)) + return nil + + default: + p.Outputf("Created Wrapping Key for project %q. Wrapping Key ID: %s\n", projectLabel, utils.PtrString(resp.Id)) + return nil + } +} + +func configureFlags(cmd *cobra.Command) { + cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS Key Ring") + cmd.Flags().String(algorithmFlag, "", "En-/Decryption algorithm") + cmd.Flags().String(backendFlag, "software", "The backend that is responsible for maintaining this wrapping key") + cmd.Flags().String(displayNameFlag, "", "The display name to distinguish multiple wrapping keys") + cmd.Flags().String(descriptionFlag, "", "Optinal description of the Wrapping Key") + cmd.Flags().String(purposeFlag, "", "Purpose of the Wrapping Key. Enum: 'wrap_symmetric_key', 'wrap_asymmetric_key' ") + + err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, algorithmFlag, purposeFlag, displayNameFlag) + cobra.CheckErr(err) +} diff --git a/internal/cmd/beta/kms/wrappingkey/delete/delete.go b/internal/cmd/beta/kms/wrappingkey/delete/delete.go new file mode 100644 index 000000000..1d2f6d37e --- /dev/null +++ b/internal/cmd/beta/kms/wrappingkey/delete/delete.go @@ -0,0 +1,136 @@ +package delete + +import ( + "context" + "fmt" + + "github.com/spf13/cobra" + "github.com/stackitcloud/stackit-cli/internal/cmd/params" + "github.com/stackitcloud/stackit-cli/internal/pkg/args" + "github.com/stackitcloud/stackit-cli/internal/pkg/errors" + "github.com/stackitcloud/stackit-cli/internal/pkg/examples" + "github.com/stackitcloud/stackit-cli/internal/pkg/flags" + "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" + "github.com/stackitcloud/stackit-cli/internal/pkg/print" + kmsUtils "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/utils" + + "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/client" + "github.com/stackitcloud/stackit-cli/internal/pkg/utils" + "github.com/stackitcloud/stackit-sdk-go/services/kms" +) + +const ( + keyRingIdFlag = "key-ring" + wrappingKeyIdFlag = "wrapping-key" +) + +type inputModel struct { + *globalflags.GlobalFlagModel + keyRingId string + wrappingKey string +} + +func NewCmd(params *params.CmdParams) *cobra.Command { + cmd := &cobra.Command{ + Use: "delete", + Short: "Deletes a KMS Wrapping Key", + Long: "Deletes a KMS Wrapping Key inside a specific Key Ring.", + Args: args.NoArgs, + Example: examples.Build( + examples.NewExample( + `Delete a KMS Wrapping Key "my-wrapping-key-id" inside the Key Ring "my-key-ring-id"`, + `$ stackit beta kms keyring delete --key-ring "my-key-ring-id" --wrapping-key "my-wrapping-key-id"`), + ), + RunE: func(cmd *cobra.Command, _ []string) error { + ctx := context.Background() + model, err := parseInput(params.Printer, cmd) + if err != nil { + return err + } + + // Configure API client + apiClient, err := client.ConfigureClient(params.Printer, params.CliVersion) + if err != nil { + return err + } + + wrappingKeyName, err := kmsUtils.GetWrappingKeyName(ctx, apiClient, model.ProjectId, model.Region, model.keyRingId, model.wrappingKey) + if err != nil { + params.Printer.Debug(print.ErrorLevel, "get wrapping key name: %v", err) + wrappingKeyName = model.wrappingKey + } + + if !model.AssumeYes { + prompt := fmt.Sprintf("Are you sure you want to delete key ring %q? (This cannot be undone)", wrappingKeyName) + err = params.Printer.PromptForConfirmation(prompt) + if err != nil { + return err + } + } + + // Call API + req := buildRequest(ctx, model, apiClient) + err = req.Execute() + if err != nil { + return fmt.Errorf("delete KMS Wrapping Key: %w", err) + } + + // Wait for async operation not relevant. Wrapping key deletion is synchronous + // https://pkg.go.dev/github.com/stackitcloud/stackit-sdk-go/services/kms@v0.5.1/wait + + params.Printer.Info("Deleted wrapping key %q\n", wrappingKeyName) + return nil + }, + } + + configureFlags(cmd) + return cmd +} + +func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { + globalFlags := globalflags.Parse(p, cmd) + if globalFlags.ProjectId == "" { + return nil, &errors.ProjectIdError{} + } + + keyRingId := flags.FlagToStringValue(p, cmd, keyRingIdFlag) + wrappingKeyId := flags.FlagToStringValue(p, cmd, wrappingKeyIdFlag) + + // Validate the uuid format of the IDs + errKeyRing := utils.ValidateUUID(keyRingId) + errWrappingKey := utils.ValidateUUID(wrappingKeyId) + if errKeyRing != nil || errWrappingKey != nil { + return nil, &errors.DSAInputPlanError{ + Cmd: cmd, + } + } + + model := inputModel{ + GlobalFlagModel: globalFlags, + keyRingId: keyRingId, + wrappingKey: wrappingKeyId, + } + + if p.IsVerbosityDebug() { + modelStr, err := print.BuildDebugStrFromInputModel(model) + if err != nil { + p.Debug(print.ErrorLevel, "convert model to string for debugging: %v", err) + } else { + p.Debug(print.DebugLevel, "parsed input values: %s", modelStr) + } + } + + return &model, nil +} + +func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClient) kms.ApiDeleteWrappingKeyRequest { + req := apiClient.DeleteWrappingKey(ctx, model.ProjectId, model.Region, model.keyRingId, model.wrappingKey) + return req +} + +func configureFlags(cmd *cobra.Command) { + cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS Key Ring where the Wrapping Key is stored") + cmd.Flags().Var(flags.UUIDFlag(), wrappingKeyIdFlag, "ID of the actual Wrapping Key") + err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, wrappingKeyIdFlag) + cobra.CheckErr(err) +} diff --git a/internal/cmd/beta/kms/wrappingkey/list/list.go b/internal/cmd/beta/kms/wrappingkey/list/list.go new file mode 100644 index 000000000..a0b4bb2b0 --- /dev/null +++ b/internal/cmd/beta/kms/wrappingkey/list/list.go @@ -0,0 +1,149 @@ +package list + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/goccy/go-yaml" + "github.com/spf13/cobra" + "github.com/stackitcloud/stackit-cli/internal/cmd/params" + "github.com/stackitcloud/stackit-cli/internal/pkg/args" + "github.com/stackitcloud/stackit-cli/internal/pkg/errors" + "github.com/stackitcloud/stackit-cli/internal/pkg/examples" + "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" + "github.com/stackitcloud/stackit-cli/internal/pkg/print" + "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/client" + "github.com/stackitcloud/stackit-cli/internal/pkg/tables" + "github.com/stackitcloud/stackit-cli/internal/pkg/utils" + "github.com/stackitcloud/stackit-sdk-go/services/kms" +) + +const ( + keyRingIdArg = "KEYRING_ID" +) + +type inputModel struct { + *globalflags.GlobalFlagModel + keyRingId string +} + +func NewCmd(params *params.CmdParams) *cobra.Command { + cmd := &cobra.Command{ + Use: fmt.Sprintf("list %s", keyRingIdArg), + Short: "Lists all KMS Wrapping Keys", + Long: "Lists all KMS Wrapping Keys inside a key ring.", + Args: args.SingleArg(keyRingIdArg, utils.ValidateUUID), + Example: examples.Build( + // Enforce a specific region for the KMS + examples.NewExample( + `List all KMS Wrapping Keys for the key ring "xxx"`, + "$ stackit beta kms wrappingkeys list xxx"), + examples.NewExample( + `List all KMS Wrapping Keys in JSON format`, + "$ stackit beta kms wrappingkeys list xxx --output-format json"), + ), + RunE: func(cmd *cobra.Command, args []string) error { + ctx := context.Background() + model, err := parseInput(params.Printer, cmd, args) + if err != nil { + return err + } + + // Configure API client + apiClient, err := client.ConfigureClient(params.Printer, params.CliVersion) + if err != nil { + return err + } + + // Call API + req := buildRequest(ctx, model, apiClient) + resp, err := req.Execute() + if err != nil { + return fmt.Errorf("get KMS Wrapping Keys: %w", err) + } + if resp.WrappingKeys == nil || len(*resp.WrappingKeys) == 0 { + params.Printer.Info("No Wrapping Keys found for project %q in region %q under the key ring %q\n", model.ProjectId, model.Region, model.keyRingId) + return nil + } + wrappingKeys := *resp.WrappingKeys + + return outputResult(params.Printer, model.OutputFormat, wrappingKeys) + }, + } + return cmd +} + +func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inputModel, error) { + keyRingId := inputArgs[0] + + globalFlags := globalflags.Parse(p, cmd) + if globalFlags.ProjectId == "" { + return nil, &errors.ProjectIdError{} + } + + model := inputModel{ + GlobalFlagModel: globalFlags, + keyRingId: keyRingId, + } + + if p.IsVerbosityDebug() { + modelStr, err := print.BuildDebugStrFromInputModel(model) + if err != nil { + p.Debug(print.ErrorLevel, "convert model to string for debugging: %v", err) + } else { + p.Debug(print.DebugLevel, "parsed input values: %s", modelStr) + } + } + + return &model, nil +} + +func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClient) kms.ApiListWrappingKeysRequest { + req := apiClient.ListWrappingKeys(ctx, model.ProjectId, model.Region, model.keyRingId) + return req +} + +func outputResult(p *print.Printer, outputFormat string, wrappingKeys []kms.WrappingKey) error { + switch outputFormat { + case print.JSONOutputFormat: + details, err := json.MarshalIndent(wrappingKeys, "", " ") + if err != nil { + return fmt.Errorf("marshal KMS Wrapping Keys list: %w", err) + } + p.Outputln(string(details)) + + return nil + case print.YAMLOutputFormat: + details, err := yaml.MarshalWithOptions(wrappingKeys, yaml.IndentSequence(true), yaml.UseJSONMarshaler()) + if err != nil { + return fmt.Errorf("marshal KMS Wrapping Keys list: %w", err) + } + p.Outputln(string(details)) + + return nil + default: + table := tables.NewTable() + table.SetHeader("ID", "NAME", "SCOPE", "ALGORITHM", "EXPIRES AT", "STATUS") + + for i := range wrappingKeys { + wrappingKey := wrappingKeys[i] + table.AddRow( + utils.PtrString(wrappingKey.Id), + utils.PtrString(wrappingKey.DisplayName), + utils.PtrString(wrappingKey.Purpose), + utils.PtrString(wrappingKey.Algorithm), + // utils.PtrString(wrappingKey.CreatedAt), + utils.PtrString(wrappingKey.ExpiresAt), + utils.PtrString(wrappingKey.State), + ) + } + + err := table.Display(p) + if err != nil { + return fmt.Errorf("render table: %w", err) + } + + return nil + } +} diff --git a/internal/cmd/beta/kms/wrappingkey/wrappingkey.go b/internal/cmd/beta/kms/wrappingkey/wrappingkey.go new file mode 100644 index 000000000..474df3487 --- /dev/null +++ b/internal/cmd/beta/kms/wrappingkey/wrappingkey.go @@ -0,0 +1,30 @@ +package wrappingkey + +import ( + "github.com/stackitcloud/stackit-cli/internal/cmd/beta/kms/wrappingkey/create" + "github.com/stackitcloud/stackit-cli/internal/cmd/beta/kms/wrappingkey/delete" + "github.com/stackitcloud/stackit-cli/internal/cmd/beta/kms/wrappingkey/list" + "github.com/stackitcloud/stackit-cli/internal/cmd/params" + "github.com/stackitcloud/stackit-cli/internal/pkg/args" + "github.com/stackitcloud/stackit-cli/internal/pkg/utils" + + "github.com/spf13/cobra" +) + +func NewCmd(params *params.CmdParams) *cobra.Command { + cmd := &cobra.Command{ + Use: "wrappingkey", + Short: "Manage KMS Wrapping Keys", + Long: "Provides CRUD functionality for Wrapping Key operations inside the KMS", + Args: args.NoArgs, + Run: utils.CmdHelp, + } + addSubcommands(cmd, params) + return cmd +} + +func addSubcommands(cmd *cobra.Command, params *params.CmdParams) { + cmd.AddCommand(list.NewCmd(params)) + cmd.AddCommand(delete.NewCmd(params)) + cmd.AddCommand(create.NewCmd(params)) +} From 84541d64b471fd86743d24516492098121afdd04 Mon Sep 17 00:00:00 2001 From: Jan Sternagel Date: Thu, 21 Aug 2025 06:43:29 +0200 Subject: [PATCH 04/52] (missed) add kms to the beta --- internal/cmd/beta/beta.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internal/cmd/beta/beta.go b/internal/cmd/beta/beta.go index 5a007b87e..b026da770 100644 --- a/internal/cmd/beta/beta.go +++ b/internal/cmd/beta/beta.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/stackitcloud/stackit-cli/internal/cmd/beta/alb" + "github.com/stackitcloud/stackit-cli/internal/cmd/beta/kms" "github.com/stackitcloud/stackit-cli/internal/cmd/beta/sqlserverflex" "github.com/stackitcloud/stackit-cli/internal/cmd/params" "github.com/stackitcloud/stackit-cli/internal/pkg/args" @@ -38,4 +39,5 @@ func NewCmd(params *params.CmdParams) *cobra.Command { func addSubcommands(cmd *cobra.Command, params *params.CmdParams) { cmd.AddCommand(sqlserverflex.NewCmd(params)) cmd.AddCommand(alb.NewCmd(params)) + cmd.AddCommand(kms.NewCmd(params)) } From 13bbc8c87c5599e2d182f890072cd76b4f1ea86b Mon Sep 17 00:00:00 2001 From: Jan Sternagel Date: Sat, 23 Aug 2025 23:56:50 +0200 Subject: [PATCH 05/52] added unit tests --- internal/cmd/beta/kms/key/create/create.go | 6 +- .../cmd/beta/kms/key/create/create_test.go | 323 +++++++++++++++++ .../cmd/beta/kms/key/delete/delete_test.go | 227 ++++++++++++ .../cmd/beta/kms/key/importKey/importKey.go | 15 +- .../beta/kms/key/importKey/importKey_test.go | 335 ++++++++++++++++++ internal/cmd/beta/kms/key/list/list.go | 8 +- internal/cmd/beta/kms/key/list/list_test.go | 252 +++++++++++++ .../cmd/beta/kms/key/restore/restore_test.go | 227 ++++++++++++ .../cmd/beta/kms/key/rotate/rotate_test.go | 271 ++++++++++++++ .../beta/kms/keyring/create/create_test.go | 250 +++++++++++++ .../cmd/beta/kms/keyring/delete/delete.go | 10 +- .../beta/kms/keyring/delete/delete_test.go | 212 +++++++++++ .../cmd/beta/kms/keyring/list/list_test.go | 211 +++++++++++ .../beta/kms/version/destroy/destroy_test.go | 252 +++++++++++++ .../beta/kms/version/disable/disable_test.go | 252 +++++++++++++ .../beta/kms/version/enable/enable_test.go | 252 +++++++++++++ .../cmd/beta/kms/version/list/list_test.go | 268 ++++++++++++++ .../beta/kms/version/restore/restore_test.go | 252 +++++++++++++ .../kms/wrappingkey/create/create_test.go | 314 ++++++++++++++++ .../cmd/beta/kms/wrappingkey/delete/delete.go | 14 +- .../kms/wrappingkey/delete/delete_test.go | 220 ++++++++++++ .../cmd/beta/kms/wrappingkey/list/list.go | 8 +- .../beta/kms/wrappingkey/list/list_test.go | 258 ++++++++++++++ 23 files changed, 4411 insertions(+), 26 deletions(-) create mode 100644 internal/cmd/beta/kms/key/create/create_test.go create mode 100644 internal/cmd/beta/kms/key/delete/delete_test.go create mode 100644 internal/cmd/beta/kms/key/importKey/importKey_test.go create mode 100644 internal/cmd/beta/kms/key/list/list_test.go create mode 100644 internal/cmd/beta/kms/key/restore/restore_test.go create mode 100644 internal/cmd/beta/kms/key/rotate/rotate_test.go create mode 100644 internal/cmd/beta/kms/keyring/create/create_test.go create mode 100644 internal/cmd/beta/kms/keyring/delete/delete_test.go create mode 100644 internal/cmd/beta/kms/keyring/list/list_test.go create mode 100644 internal/cmd/beta/kms/version/destroy/destroy_test.go create mode 100644 internal/cmd/beta/kms/version/disable/disable_test.go create mode 100644 internal/cmd/beta/kms/version/enable/enable_test.go create mode 100644 internal/cmd/beta/kms/version/list/list_test.go create mode 100644 internal/cmd/beta/kms/version/restore/restore_test.go create mode 100644 internal/cmd/beta/kms/wrappingkey/create/create_test.go create mode 100644 internal/cmd/beta/kms/wrappingkey/delete/delete_test.go create mode 100644 internal/cmd/beta/kms/wrappingkey/list/list_test.go diff --git a/internal/cmd/beta/kms/key/create/create.go b/internal/cmd/beta/kms/key/create/create.go index 1c5407545..035dba2dc 100644 --- a/internal/cmd/beta/kms/key/create/create.go +++ b/internal/cmd/beta/kms/key/create/create.go @@ -40,7 +40,7 @@ type inputModel struct { Backend string // Keep "backend" as a variable, but set the default to "software" (see UI) Description *string Name *string - ImportOnly *bool // Default false + ImportOnly bool // Default false Purpose *string } @@ -119,7 +119,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { Backend: flags.FlagWithDefaultToStringValue(p, cmd, backendFlag), Name: flags.FlagToStringPointer(p, cmd, displayNameFlag), Description: flags.FlagToStringPointer(p, cmd, descriptionFlag), - ImportOnly: flags.FlagToBoolPointer(p, cmd, importOnlyFlag), + ImportOnly: flags.FlagToBoolValue(p, cmd, importOnlyFlag), Purpose: flags.FlagToStringPointer(p, cmd, purposeFlag), } @@ -149,7 +149,7 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient kmsKeyClient Algorithm: kms.CreateKeyPayloadGetAlgorithmAttributeType(model.Algorithm), Backend: kms.CreateKeyPayloadGetBackendAttributeType(&model.Backend), Purpose: kms.CreateKeyPayloadGetPurposeAttributeType(model.Purpose), - ImportOnly: model.ImportOnly, + ImportOnly: &model.ImportOnly, }) return req, nil } diff --git a/internal/cmd/beta/kms/key/create/create_test.go b/internal/cmd/beta/kms/key/create/create_test.go new file mode 100644 index 000000000..e62247fcd --- /dev/null +++ b/internal/cmd/beta/kms/key/create/create_test.go @@ -0,0 +1,323 @@ +package create + +import ( + "context" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/google/uuid" + "github.com/spf13/cobra" + "github.com/stackitcloud/stackit-cli/internal/cmd/params" + "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" + "github.com/stackitcloud/stackit-cli/internal/pkg/print" + "github.com/stackitcloud/stackit-cli/internal/pkg/utils" + "github.com/stackitcloud/stackit-sdk-go/services/kms" +) + +const ( + testRegion = "eu01" +) + +type testCtxKey struct{} + +var ( + testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") + testClient = &kms.APIClient{} + testProjectId = uuid.NewString() + testKeyRingId = uuid.NewString() + testAlgorithm = "some_rsa_2048" + testDisplayName = "my-key" + testPurpose = "asymmetric_encrypt_decrypt" + testDescription = "my key description" + testImportOnly = "true" + testBackend = "notSoftware" +) + +// Flags +func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]string { + flagValues := map[string]string{ + globalflags.ProjectIdFlag: testProjectId, + globalflags.RegionFlag: testRegion, + keyRingIdFlag: testKeyRingId, + algorithmFlag: testAlgorithm, + displayNameFlag: testDisplayName, + purposeFlag: testPurpose, + descriptionFlag: testDescription, + importOnlyFlag: testImportOnly, + backendFlag: testBackend, + } + for _, mod := range mods { + mod(flagValues) + } + return flagValues +} + +// Input Model +func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { + model := &inputModel{ + GlobalFlagModel: &globalflags.GlobalFlagModel{ + ProjectId: testProjectId, + Region: testRegion, + Verbosity: globalflags.VerbosityDefault, + }, + KeyRingId: testKeyRingId, + Algorithm: utils.Ptr(testAlgorithm), + Name: utils.Ptr(testDisplayName), + Purpose: utils.Ptr(testPurpose), + Description: utils.Ptr(testDescription), + ImportOnly: true, // Watch out: ImportOnly is not testImportOnly! + Backend: testBackend, + } + for _, mod := range mods { + mod(model) + } + return model +} + +// Request +func fixtureRequest(mods ...func(request *kms.ApiCreateKeyRequest)) kms.ApiCreateKeyRequest { + request := testClient.CreateKey(testCtx, testProjectId, testRegion, testKeyRingId) + request = request.CreateKeyPayload(kms.CreateKeyPayload{ + Algorithm: kms.CreateKeyPayloadGetAlgorithmAttributeType(utils.Ptr(testAlgorithm)), + DisplayName: utils.Ptr(testDisplayName), + Purpose: kms.CreateKeyPayloadGetPurposeAttributeType(utils.Ptr(testPurpose)), + Description: utils.Ptr(testDescription), + ImportOnly: utils.Ptr(true), + Backend: kms.CreateKeyPayloadGetBackendAttributeType(utils.Ptr(testBackend)), + }) + + for _, mod := range mods { + mod(&request) + } + return request +} + +func TestParseInput(t *testing.T) { + tests := []struct { + description string + flagValues map[string]string + isValid bool + expectedModel *inputModel + }{ + { + description: "base", + flagValues: fixtureFlagValues(), + isValid: true, + expectedModel: fixtureInputModel(), + }, + { + description: "optional flags omitted", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, descriptionFlag) + delete(flagValues, importOnlyFlag) + delete(flagValues, backendFlag) + }), + isValid: true, + expectedModel: fixtureInputModel(func(model *inputModel) { + model.Description = nil + model.ImportOnly = false + model.Backend = "software" + }), + }, + { + description: "no values provided", + flagValues: map[string]string{}, + isValid: false, + }, + { + description: "project id missing", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, globalflags.ProjectIdFlag) + }), + isValid: false, + }, + { + description: "project id invalid 1", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[globalflags.ProjectIdFlag] = "" + }), + isValid: false, + }, + { + description: "project id invalid 2", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[globalflags.ProjectIdFlag] = "invalid-uuid" + }), + isValid: false, + }, + { + description: "key ring id missing (required)", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, keyRingIdFlag) + }), + isValid: false, + }, + { + description: "key ring id invalid", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyRingIdFlag] = "invalid-uuid" + }), + isValid: false, + }, + { + description: "algorithm missing (required)", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, algorithmFlag) + }), + isValid: false, + }, + { + description: "name missing (required)", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, displayNameFlag) + }), + isValid: false, + }, + { + description: "purpose missing (required)", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, purposeFlag) + }), + isValid: false, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + cmd := &cobra.Command{} + err := globalflags.Configure(cmd.Flags()) + if err != nil { + t.Fatalf("configure global flags: %v", err) + } + + configureFlags(cmd) + + 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) + } + } + + err = cmd.ValidateRequiredFlags() + if err != nil { + if !tt.isValid { + return + } + t.Fatalf("error validating flags: %v", err) + } + + p := print.NewPrinter() + model, err := parseInput(p, cmd) + 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(tt.expectedModel, model) + if diff != "" { + t.Fatalf("Data does not match: %s", diff) + } + }) + } +} + +func TestBuildRequest(t *testing.T) { + tests := []struct { + description string + model *inputModel + expectedRequest kms.ApiCreateKeyRequest + }{ + { + description: "base case", + model: fixtureInputModel(), + expectedRequest: fixtureRequest(), + }, + { + description: "no optional values", + model: fixtureInputModel(func(model *inputModel) { + model.Description = nil + model.ImportOnly = false + }), + expectedRequest: fixtureRequest().CreateKeyPayload(kms.CreateKeyPayload{ + Algorithm: kms.CreateKeyPayloadGetAlgorithmAttributeType(utils.Ptr(testAlgorithm)), + DisplayName: utils.Ptr(testDisplayName), + Purpose: kms.CreateKeyPayloadGetPurposeAttributeType(utils.Ptr(testPurpose)), + Description: nil, + ImportOnly: utils.Ptr(false), + Backend: kms.CreateKeyPayloadGetBackendAttributeType(utils.Ptr(testBackend)), + }), + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + request, err := buildRequest(testCtx, tt.model, testClient) + if err != nil { + t.Fatalf("error building request: %v", err) + } + + diff := cmp.Diff(tt.expectedRequest, request, + cmp.AllowUnexported(tt.expectedRequest), + cmpopts.EquateComparable(testCtx), + ) + if diff != "" { + t.Fatalf("Data does not match: %s", diff) + } + }) + } +} + +func TestOutputResult(t *testing.T) { + tests := []struct { + description string + key *kms.Key + outputFormat string + projectLabel string + wantErr bool + }{ + { + description: "nil response", + key: nil, + wantErr: true, + }, + { + description: "default output", + key: &kms.Key{}, + projectLabel: "my-project", + wantErr: false, + }, + { + description: "json output", + key: &kms.Key{}, + outputFormat: print.JSONOutputFormat, + wantErr: false, + }, + { + description: "yaml output", + key: &kms.Key{}, + outputFormat: print.YAMLOutputFormat, + wantErr: false, + }, + } + + p := print.NewPrinter() + p.Cmd = NewCmd(¶ms.CmdParams{Printer: p}) + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + err := outputResult(p, tt.outputFormat, tt.projectLabel, tt.key) + if (err != nil) != tt.wantErr { + t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/internal/cmd/beta/kms/key/delete/delete_test.go b/internal/cmd/beta/kms/key/delete/delete_test.go new file mode 100644 index 000000000..61e02c45e --- /dev/null +++ b/internal/cmd/beta/kms/key/delete/delete_test.go @@ -0,0 +1,227 @@ +package delete + +import ( + "context" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/google/uuid" + "github.com/spf13/cobra" + "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" + "github.com/stackitcloud/stackit-cli/internal/pkg/print" + "github.com/stackitcloud/stackit-sdk-go/services/kms" +) + +const ( + testRegion = "eu02" +) + +type testCtxKey struct{} + +var ( + testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") + testClient = &kms.APIClient{} + testProjectId = uuid.NewString() + testKeyRingId = uuid.NewString() + testKeyId = uuid.NewString() +) + +// Flags +func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]string { + flagValues := map[string]string{ + globalflags.ProjectIdFlag: testProjectId, + globalflags.RegionFlag: testRegion, + keyRingIdFlag: testKeyRingId, + keyIdFlag: testKeyId, + } + for _, mod := range mods { + mod(flagValues) + } + return flagValues +} + +// Input Model +func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { + model := &inputModel{ + GlobalFlagModel: &globalflags.GlobalFlagModel{ + ProjectId: testProjectId, + Region: testRegion, + Verbosity: globalflags.VerbosityDefault, + }, + KeyRingId: testKeyRingId, + KeyId: testKeyId, + } + for _, mod := range mods { + mod(model) + } + return model +} + +// Request +func fixtureRequest(mods ...func(request *kms.ApiDeleteKeyRequest)) kms.ApiDeleteKeyRequest { + request := testClient.DeleteKey(testCtx, testProjectId, testRegion, testKeyRingId, testKeyId) + for _, mod := range mods { + mod(&request) + } + return request +} + +func TestParseInput(t *testing.T) { + tests := []struct { + description string + flagValues map[string]string + isValid bool + expectedModel *inputModel + }{ + { + description: "base", + flagValues: fixtureFlagValues(), + expectedModel: fixtureInputModel(), + isValid: true, + }, + { + description: "no values", + flagValues: map[string]string{}, + isValid: false, + }, + { + description: "project id missing", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, globalflags.ProjectIdFlag) + }), + isValid: false, + }, + { + description: "project id invalid 1", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[globalflags.ProjectIdFlag] = "" + }), + isValid: false, + }, + { + description: "project id invalid 2", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[globalflags.ProjectIdFlag] = "invalid-uuid" + }), + isValid: false, + }, + { + description: "key ring id missing", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, keyRingIdFlag) + }), + isValid: false, + }, + { + description: "key ring id invalid 1", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyRingIdFlag] = "" + }), + isValid: false, + }, + { + description: "key ring id invalid 2", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyRingIdFlag] = "invalid-uuid" + }), + isValid: false, + }, + { + description: "key id missing", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, keyIdFlag) + }), + isValid: false, + }, + { + description: "key id invalid 1", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyIdFlag] = "" + }), + isValid: false, + }, + { + description: "key id invalid 2", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyIdFlag] = "invalid-uuid" + }), + isValid: false, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + cmd := &cobra.Command{} + err := globalflags.Configure(cmd.Flags()) + if err != nil { + t.Fatalf("configure global flags: %v", err) + } + + configureFlags(cmd) + + 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) + } + } + + err = cmd.ValidateRequiredFlags() + if err != nil { + if !tt.isValid { + return + } + t.Fatalf("error validating flags: %v", err) + } + + p := print.NewPrinter() + model, err := parseInput(p, cmd) + 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(tt.expectedModel, model) + if diff != "" { + t.Fatalf("Data does not match: %s", diff) + } + }) + } +} + +func TestBuildRequest(t *testing.T) { + tests := []struct { + description string + model *inputModel + expectedRequest kms.ApiDeleteKeyRequest + }{ + { + description: "base case", + model: fixtureInputModel(), + expectedRequest: fixtureRequest(), + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + request := buildRequest(testCtx, tt.model, testClient) + + diff := cmp.Diff(request, tt.expectedRequest, + cmp.AllowUnexported(tt.expectedRequest), + cmpopts.EquateComparable(testCtx), + ) + if diff != "" { + t.Fatalf("Data does not match: %s", diff) + } + }) + } +} diff --git a/internal/cmd/beta/kms/key/importKey/importKey.go b/internal/cmd/beta/kms/key/importKey/importKey.go index aab53fe96..935c1ef9d 100644 --- a/internal/cmd/beta/kms/key/importKey/importKey.go +++ b/internal/cmd/beta/kms/key/importKey/importKey.go @@ -2,6 +2,7 @@ package importKey import ( "context" + "encoding/base64" "encoding/json" "fmt" @@ -105,13 +106,21 @@ func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { return nil, &cliErr.ProjectIdError{} } - // What checks could this need? - // I would rather let the creation fail instead of checking all possible algorithms + // WrappedKey needs to be base64 encoded + var wrappedKey *string = flags.FlagToStringPointer(p, cmd, wrappedKeyFlag) + _, err := base64.StdEncoding.DecodeString(*wrappedKey) + if err != nil || *wrappedKey == "" { + return nil, &cliErr.FlagValidationError{ + Flag: wrappedKeyFlag, + Details: "The 'wrappedKey' argument is required and needs to be base64 encoded.", + } + } + model := inputModel{ GlobalFlagModel: globalFlags, KeyRingId: flags.FlagToStringValue(p, cmd, keyRingIdFlag), KeyId: flags.FlagToStringValue(p, cmd, keyIdFlag), - WrappedKey: flags.FlagToStringPointer(p, cmd, wrappedKeyFlag), + WrappedKey: wrappedKey, WrappingKeyId: flags.FlagToStringPointer(p, cmd, wrappingKeyIdFlag), } diff --git a/internal/cmd/beta/kms/key/importKey/importKey_test.go b/internal/cmd/beta/kms/key/importKey/importKey_test.go new file mode 100644 index 000000000..140f382e6 --- /dev/null +++ b/internal/cmd/beta/kms/key/importKey/importKey_test.go @@ -0,0 +1,335 @@ +package importKey + +import ( + "context" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/google/uuid" + "github.com/spf13/cobra" + "github.com/stackitcloud/stackit-cli/internal/cmd/params" + "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" + "github.com/stackitcloud/stackit-cli/internal/pkg/print" + "github.com/stackitcloud/stackit-sdk-go/services/kms" +) + +const ( + testRegion = "eu01" +) + +type testCtxKey struct{} + +var ( + testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") + testClient = &kms.APIClient{} + testProjectId = uuid.NewString() + testKeyRingId = uuid.NewString() + testKeyId = uuid.NewString() + testWrappingKeyId = uuid.NewString() + testWrappedKey = "SnVzdCBzYXlpbmcgaGV5Oyk=" +) + +// Flags +func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]string { + flagValues := map[string]string{ + globalflags.ProjectIdFlag: testProjectId, + globalflags.RegionFlag: testRegion, + keyRingIdFlag: testKeyRingId, + keyIdFlag: testKeyId, + wrappedKeyFlag: testWrappedKey, + wrappingKeyIdFlag: testWrappingKeyId, + } + for _, mod := range mods { + mod(flagValues) + } + return flagValues +} + +// Input Model +func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { + model := &inputModel{ + GlobalFlagModel: &globalflags.GlobalFlagModel{ + ProjectId: testProjectId, + Region: testRegion, + Verbosity: globalflags.VerbosityDefault, + }, + KeyRingId: testKeyRingId, + KeyId: testKeyId, + WrappedKey: &testWrappedKey, + WrappingKeyId: &testWrappingKeyId, + } + for _, mod := range mods { + mod(model) + } + return model +} + +// Request +func fixtureRequest(mods ...func(request *kms.ApiImportKeyRequest)) kms.ApiImportKeyRequest { + request := testClient.ImportKey(testCtx, testProjectId, testRegion, testKeyRingId, testKeyId) + request = request.ImportKeyPayload(kms.ImportKeyPayload{ + WrappedKey: &testWrappedKey, + WrappingKeyId: &testWrappingKeyId, + }) + + for _, mod := range mods { + mod(&request) + } + return request +} + +func TestParseInput(t *testing.T) { + tests := []struct { + description string + flagValues map[string]string + isValid bool + expectedModel *inputModel + }{ + { + description: "base", + flagValues: fixtureFlagValues(), + isValid: true, + expectedModel: fixtureInputModel(), + }, + { + description: "no values provided", + flagValues: map[string]string{}, + isValid: false, + }, + { + description: "project id missing", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, globalflags.ProjectIdFlag) + }), + isValid: false, + }, + { + description: "project id invalid 1", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[globalflags.ProjectIdFlag] = "" + }), + isValid: false, + }, + { + description: "project id invalid 2", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[globalflags.ProjectIdFlag] = "invalid-uuid" + }), + isValid: false, + }, + { + description: "key ring id missing (required)", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, keyRingIdFlag) + }), + isValid: false, + }, + { + description: "key ring id invalid 1", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyRingIdFlag] = "" + }), + isValid: false, + }, + { + description: "key ring id invalid 2", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyRingIdFlag] = "invalid-uuid" + }), + isValid: false, + }, + { + description: "key id missing (required)", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, keyIdFlag) + }), + isValid: false, + }, + { + description: "key id invalid 1", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyIdFlag] = "" + }), + isValid: false, + }, + { + description: "key id invalid 2", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyIdFlag] = "invalid-uuid" + }), + isValid: false, + }, + { + description: "wrapping key id missing (required)", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, wrappingKeyIdFlag) + }), + isValid: false, + }, + { + description: "wrapping key id invalid 1", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[wrappingKeyIdFlag] = "" + }), + isValid: false, + }, + { + description: "wrapping key id invalid 2", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[wrappingKeyIdFlag] = "invalid-uuid" + }), + isValid: false, + }, + { + description: "wrapped key missing (required)", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, wrappedKeyFlag) + }), + isValid: false, + }, + { + description: "wrapped key invalid 1", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[wrappedKeyFlag] = "" + }), + isValid: false, + }, + { + description: "wrapped key invalid 2 - not base64", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[wrappedKeyFlag] = "Not Base 64" + }), + isValid: false, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + cmd := &cobra.Command{} + err := globalflags.Configure(cmd.Flags()) + if err != nil { + t.Fatalf("configure global flags: %v", err) + } + + configureFlags(cmd) + + 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) + } + } + + err = cmd.ValidateRequiredFlags() + if err != nil { + if !tt.isValid { + return + } + t.Fatalf("error validating flags: %v", err) + } + + p := print.NewPrinter() + model, err := parseInput(p, cmd) + 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(tt.expectedModel, model) + if diff != "" { + t.Fatalf("Data does not match: %s", diff) + } + }) + } +} + +func TestBuildRequest(t *testing.T) { + tests := []struct { + description string + model *inputModel + expectedRequest kms.ApiImportKeyRequest + }{ + { + description: "base case", + model: fixtureInputModel(), + expectedRequest: fixtureRequest(), + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + request, err := buildRequest(testCtx, tt.model, testClient) + if err != nil { + t.Fatalf("error building request: %v", err) + } + + diff := cmp.Diff(tt.expectedRequest, request, + cmp.AllowUnexported(tt.expectedRequest), + cmpopts.EquateComparable(testCtx), + ) + if diff != "" { + t.Fatalf("Data does not match: %s", diff) + } + }) + } +} + +func TestOutputResult(t *testing.T) { + tests := []struct { + description string + version *kms.Version + outputFormat string + keyRingName string + keyName string + wantErr bool + }{ + { + description: "nil response", + version: nil, + wantErr: true, + }, + { + description: "default output", + version: &kms.Version{}, + keyRingName: "my-key-ring", + keyName: "my-key", + wantErr: false, + }, + { + description: "json output", + version: &kms.Version{}, + outputFormat: print.JSONOutputFormat, + keyRingName: "my-key-ring", + keyName: "my-key", + wantErr: false, + }, + { + description: "yaml output", + version: &kms.Version{}, + outputFormat: print.YAMLOutputFormat, + keyRingName: "my-key-ring", + keyName: "my-key", + wantErr: false, + }, + } + + p := print.NewPrinter() + p.Cmd = NewCmd(¶ms.CmdParams{Printer: p}) + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + err := outputResult(p, tt.outputFormat, tt.keyRingName, tt.keyName, tt.version) + if (err != nil) != tt.wantErr { + t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/internal/cmd/beta/kms/key/list/list.go b/internal/cmd/beta/kms/key/list/list.go index 45f9f4925..191acccd5 100644 --- a/internal/cmd/beta/kms/key/list/list.go +++ b/internal/cmd/beta/kms/key/list/list.go @@ -25,7 +25,7 @@ const ( type inputModel struct { *globalflags.GlobalFlagModel - keyRingId string + KeyRingId string } func NewCmd(params *params.CmdParams) *cobra.Command { @@ -62,7 +62,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { return fmt.Errorf("get KMS Keys: %w", err) } if resp.Keys == nil || len(*resp.Keys) == 0 { - params.Printer.Info("No Keys found for project %q in region %q under the key ring %q\n", model.ProjectId, model.Region, model.keyRingId) + params.Printer.Info("No Keys found for project %q in region %q under the key ring %q\n", model.ProjectId, model.Region, model.KeyRingId) return nil } keys := *resp.Keys @@ -84,7 +84,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu model := inputModel{ GlobalFlagModel: globalFlags, - keyRingId: keyRingId, + KeyRingId: keyRingId, } if p.IsVerbosityDebug() { @@ -100,7 +100,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu } func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClient) kms.ApiListKeysRequest { - req := apiClient.ListKeys(ctx, model.ProjectId, model.Region, model.keyRingId) + req := apiClient.ListKeys(ctx, model.ProjectId, model.Region, model.KeyRingId) return req } diff --git a/internal/cmd/beta/kms/key/list/list_test.go b/internal/cmd/beta/kms/key/list/list_test.go new file mode 100644 index 000000000..1ff9d44c3 --- /dev/null +++ b/internal/cmd/beta/kms/key/list/list_test.go @@ -0,0 +1,252 @@ +package list + +import ( + "context" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/google/uuid" + "github.com/stackitcloud/stackit-cli/internal/cmd/params" + "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" + "github.com/stackitcloud/stackit-cli/internal/pkg/print" + "github.com/stackitcloud/stackit-sdk-go/services/kms" +) + +const ( + testRegion = "eu01" +) + +type testCtxKey struct{} + +var ( + testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") + testClient = &kms.APIClient{} + testProjectId = uuid.NewString() + testKeyRingId = uuid.NewString() +) + +// Args +func fixtureArgValues(mods ...func(argValues []string)) []string { + argValues := []string{ + testKeyRingId, + } + for _, mod := range mods { + mod(argValues) + } + return argValues +} + +// Flags +func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]string { + flagValues := map[string]string{ + globalflags.ProjectIdFlag: testProjectId, + globalflags.RegionFlag: testRegion, + } + for _, mod := range mods { + mod(flagValues) + } + return flagValues +} + +// Input Model +func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { + model := &inputModel{ + GlobalFlagModel: &globalflags.GlobalFlagModel{ + ProjectId: testProjectId, + Region: testRegion, + Verbosity: globalflags.VerbosityDefault, + }, + KeyRingId: testKeyRingId, + } + for _, mod := range mods { + mod(model) + } + return model +} + +// Request +func fixtureRequest(mods ...func(request *kms.ApiListKeysRequest)) kms.ApiListKeysRequest { + request := testClient.ListKeys(testCtx, testProjectId, testRegion, testKeyRingId) + for _, mod := range mods { + mod(&request) + } + return request +} + +func TestParseInput(t *testing.T) { + tests := []struct { + description string + argValues []string + flagValues map[string]string + isValid bool + expectedModel *inputModel + }{ + { + description: "base", + argValues: fixtureArgValues(), + flagValues: fixtureFlagValues(), + isValid: true, + expectedModel: fixtureInputModel(), + }, + { + description: "no args (keyRingId)", + argValues: []string{}, + flagValues: fixtureFlagValues(), + isValid: false, + }, + { + description: "invalid keyRingId", + argValues: fixtureArgValues(func(argValues []string) { + argValues[0] = "Not an uuid" + }), + flagValues: fixtureFlagValues(), + isValid: false, + }, + { + description: "project id missing", + argValues: fixtureArgValues(), + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, globalflags.ProjectIdFlag) + }), + isValid: false, + }, + { + description: "project id invalid 1", + argValues: fixtureArgValues(), + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[globalflags.ProjectIdFlag] = "" + }), + isValid: false, + }, + { + description: "project id invalid 2", + argValues: fixtureArgValues(), + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[globalflags.ProjectIdFlag] = "invalid-uuid" + }), + isValid: false, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + p := print.NewPrinter() + cmd := NewCmd(¶ms.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) + } + } + + 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(tt.expectedModel, model) + if diff != "" { + t.Fatalf("Data does not match: %s", diff) + } + }) + } +} + +func TestBuildRequest(t *testing.T) { + tests := []struct { + description string + model *inputModel + expectedRequest kms.ApiListKeysRequest + }{ + { + description: "base case", + model: fixtureInputModel(), + expectedRequest: fixtureRequest(), + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + request := buildRequest(testCtx, tt.model, testClient) + + diff := cmp.Diff(tt.expectedRequest, request, + cmp.AllowUnexported(tt.expectedRequest), + cmpopts.EquateComparable(testCtx), + ) + if diff != "" { + t.Fatalf("Data does not match: %s", diff) + } + }) + } +} + +func TestOutputResult(t *testing.T) { + tests := []struct { + description string + keys []kms.Key + outputFormat string + wantErr bool + }{ + // Response check was moved inside NewCmd() for better error feedback. + // Thus, no check for 'keys = nil' needed + { + description: "default output", + keys: []kms.Key{}, + wantErr: false, + }, + { + description: "json output", + keys: []kms.Key{}, + outputFormat: print.JSONOutputFormat, + wantErr: false, + }, + { + description: "yaml output", + keys: []kms.Key{}, + outputFormat: print.YAMLOutputFormat, + wantErr: false, + }, + } + + p := print.NewPrinter() + p.Cmd = NewCmd(¶ms.CmdParams{Printer: p}) + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + err := outputResult(p, tt.outputFormat, tt.keys) + if (err != nil) != tt.wantErr { + t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/internal/cmd/beta/kms/key/restore/restore_test.go b/internal/cmd/beta/kms/key/restore/restore_test.go new file mode 100644 index 000000000..52a375f54 --- /dev/null +++ b/internal/cmd/beta/kms/key/restore/restore_test.go @@ -0,0 +1,227 @@ +package restore + +import ( + "context" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/google/uuid" + "github.com/spf13/cobra" + "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" + "github.com/stackitcloud/stackit-cli/internal/pkg/print" + "github.com/stackitcloud/stackit-sdk-go/services/kms" +) + +const ( + testRegion = "eu02" +) + +type testCtxKey struct{} + +var ( + testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") + testClient = &kms.APIClient{} + testProjectId = uuid.NewString() + testKeyRingId = uuid.NewString() + testKeyId = uuid.NewString() +) + +// Flags +func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]string { + flagValues := map[string]string{ + globalflags.ProjectIdFlag: testProjectId, + globalflags.RegionFlag: testRegion, + keyRingIdFlag: testKeyRingId, + keyIdFlag: testKeyId, + } + for _, mod := range mods { + mod(flagValues) + } + return flagValues +} + +// Input Model +func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { + model := &inputModel{ + GlobalFlagModel: &globalflags.GlobalFlagModel{ + ProjectId: testProjectId, + Region: testRegion, + Verbosity: globalflags.VerbosityDefault, + }, + KeyRingId: testKeyRingId, + KeyId: testKeyId, + } + for _, mod := range mods { + mod(model) + } + return model +} + +// Request +func fixtureRequest(mods ...func(request *kms.ApiRestoreKeyRequest)) kms.ApiRestoreKeyRequest { + request := testClient.RestoreKey(testCtx, testProjectId, testRegion, testKeyRingId, testKeyId) + for _, mod := range mods { + mod(&request) + } + return request +} + +func TestParseInput(t *testing.T) { + tests := []struct { + description string + flagValues map[string]string + isValid bool + expectedModel *inputModel + }{ + { + description: "base", + flagValues: fixtureFlagValues(), + expectedModel: fixtureInputModel(), + isValid: true, + }, + { + description: "no values", + flagValues: map[string]string{}, + isValid: false, + }, + { + description: "project id missing", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, globalflags.ProjectIdFlag) + }), + isValid: false, + }, + { + description: "project id invalid 1", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[globalflags.ProjectIdFlag] = "" + }), + isValid: false, + }, + { + description: "project id invalid 2", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[globalflags.ProjectIdFlag] = "invalid-uuid" + }), + isValid: false, + }, + { + description: "key ring id missing", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, keyRingIdFlag) + }), + isValid: false, + }, + { + description: "key ring id invalid 1", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyRingIdFlag] = "" + }), + isValid: false, + }, + { + description: "key ring id invalid 2", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyRingIdFlag] = "invalid-uuid" + }), + isValid: false, + }, + { + description: "key id missing", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, keyIdFlag) + }), + isValid: false, + }, + { + description: "key id invalid 1", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyIdFlag] = "" + }), + isValid: false, + }, + { + description: "key id invalid 2", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyIdFlag] = "invalid-uuid" + }), + isValid: false, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + cmd := &cobra.Command{} + err := globalflags.Configure(cmd.Flags()) + if err != nil { + t.Fatalf("configure global flags: %v", err) + } + + configureFlags(cmd) + + 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) + } + } + + err = cmd.ValidateRequiredFlags() + if err != nil { + if !tt.isValid { + return + } + t.Fatalf("error validating flags: %v", err) + } + + p := print.NewPrinter() + model, err := parseInput(p, cmd) + 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(tt.expectedModel, model) + if diff != "" { + t.Fatalf("Data does not match: %s", diff) + } + }) + } +} + +func TestBuildRequest(t *testing.T) { + tests := []struct { + description string + model *inputModel + expectedRequest kms.ApiRestoreKeyRequest + }{ + { + description: "base case", + model: fixtureInputModel(), + expectedRequest: fixtureRequest(), + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + request := buildRequest(testCtx, tt.model, testClient) + + diff := cmp.Diff(request, tt.expectedRequest, + cmp.AllowUnexported(tt.expectedRequest), + cmpopts.EquateComparable(testCtx), + ) + if diff != "" { + t.Fatalf("Data does not match: %s", diff) + } + }) + } +} diff --git a/internal/cmd/beta/kms/key/rotate/rotate_test.go b/internal/cmd/beta/kms/key/rotate/rotate_test.go new file mode 100644 index 000000000..b7e8430a9 --- /dev/null +++ b/internal/cmd/beta/kms/key/rotate/rotate_test.go @@ -0,0 +1,271 @@ +package rotate + +import ( + "context" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/google/uuid" + "github.com/spf13/cobra" + "github.com/stackitcloud/stackit-cli/internal/cmd/params" + "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" + "github.com/stackitcloud/stackit-cli/internal/pkg/print" + "github.com/stackitcloud/stackit-sdk-go/services/kms" +) + +const ( + testRegion = "eu02" +) + +type testCtxKey struct{} + +var ( + testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") + testClient = &kms.APIClient{} + testProjectId = uuid.NewString() + testKeyRingId = uuid.NewString() + testKeyId = uuid.NewString() +) + +// Flags +func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]string { + flagValues := map[string]string{ + globalflags.ProjectIdFlag: testProjectId, + globalflags.RegionFlag: testRegion, + keyRingIdFlag: testKeyRingId, + keyIdFlag: testKeyId, + } + for _, mod := range mods { + mod(flagValues) + } + return flagValues +} + +// Input Model +func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { + model := &inputModel{ + GlobalFlagModel: &globalflags.GlobalFlagModel{ + ProjectId: testProjectId, + Region: testRegion, + Verbosity: globalflags.VerbosityDefault, + }, + KeyRingId: testKeyRingId, + KeyId: testKeyId, + } + for _, mod := range mods { + mod(model) + } + return model +} + +// Request +func fixtureRequest(mods ...func(request *kms.ApiRotateKeyRequest)) kms.ApiRotateKeyRequest { + request := testClient.RotateKey(testCtx, testProjectId, testRegion, testKeyRingId, testKeyId) + for _, mod := range mods { + mod(&request) + } + return request +} + +func TestParseInput(t *testing.T) { + tests := []struct { + description string + flagValues map[string]string + isValid bool + expectedModel *inputModel + }{ + { + description: "base", + flagValues: fixtureFlagValues(), + expectedModel: fixtureInputModel(), + isValid: true, + }, + { + description: "no values", + flagValues: map[string]string{}, + isValid: false, + }, + { + description: "project id missing", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, globalflags.ProjectIdFlag) + }), + isValid: false, + }, + { + description: "project id invalid 1", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[globalflags.ProjectIdFlag] = "" + }), + isValid: false, + }, + { + description: "project id invalid 2", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[globalflags.ProjectIdFlag] = "invalid-uuid" + }), + isValid: false, + }, + { + description: "key ring id missing", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, keyRingIdFlag) + }), + isValid: false, + }, + { + description: "key ring id invalid 1", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyRingIdFlag] = "" + }), + isValid: false, + }, + { + description: "key ring id invalid 2", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyRingIdFlag] = "invalid-uuid" + }), + isValid: false, + }, + { + description: "key id missing", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, keyIdFlag) + }), + isValid: false, + }, + { + description: "key id invalid 1", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyIdFlag] = "" + }), + isValid: false, + }, + { + description: "key id invalid 2", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyIdFlag] = "invalid-uuid" + }), + isValid: false, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + cmd := &cobra.Command{} + err := globalflags.Configure(cmd.Flags()) + if err != nil { + t.Fatalf("configure global flags: %v", err) + } + + configureFlags(cmd) + + 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) + } + } + + err = cmd.ValidateRequiredFlags() + if err != nil { + if !tt.isValid { + return + } + t.Fatalf("error validating flags: %v", err) + } + + p := print.NewPrinter() + model, err := parseInput(p, cmd) + 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(tt.expectedModel, model) + if diff != "" { + t.Fatalf("Data does not match: %s", diff) + } + }) + } +} + +func TestBuildRequest(t *testing.T) { + tests := []struct { + description string + model *inputModel + expectedRequest kms.ApiRotateKeyRequest + }{ + { + description: "base case", + model: fixtureInputModel(), + expectedRequest: fixtureRequest(), + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + request := buildRequest(testCtx, tt.model, testClient) + + diff := cmp.Diff(request, tt.expectedRequest, + cmp.AllowUnexported(tt.expectedRequest), + cmpopts.EquateComparable(testCtx), + ) + if diff != "" { + t.Fatalf("Data does not match: %s", diff) + } + }) + } +} + +func TestOutputResult(t *testing.T) { + tests := []struct { + description string + resp *kms.Version + outputFormat string + wantErr bool + }{ + { + description: "nil response", + resp: nil, + wantErr: true, + }, + { + description: "default output", + resp: &kms.Version{}, + wantErr: false, + }, + { + description: "json output", + resp: &kms.Version{}, + outputFormat: print.JSONOutputFormat, + wantErr: false, + }, + { + description: "yaml output", + resp: &kms.Version{}, + outputFormat: print.YAMLOutputFormat, + wantErr: false, + }, + } + + p := print.NewPrinter() + p.Cmd = NewCmd(¶ms.CmdParams{Printer: p}) + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + err := outputResult(p, tt.outputFormat, tt.resp) + if (err != nil) != tt.wantErr { + t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/internal/cmd/beta/kms/keyring/create/create_test.go b/internal/cmd/beta/kms/keyring/create/create_test.go new file mode 100644 index 000000000..7b7f8f8b4 --- /dev/null +++ b/internal/cmd/beta/kms/keyring/create/create_test.go @@ -0,0 +1,250 @@ +package create + +import ( + "context" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/google/uuid" + "github.com/spf13/cobra" + "github.com/stackitcloud/stackit-cli/internal/cmd/params" + "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" + "github.com/stackitcloud/stackit-cli/internal/pkg/print" + "github.com/stackitcloud/stackit-cli/internal/pkg/utils" + "github.com/stackitcloud/stackit-sdk-go/services/kms" +) + +const ( + testRegion = "eu01" +) + +type testCtxKey struct{} + +var ( + testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") + testClient = &kms.APIClient{} + testProjectId = uuid.NewString() + testKeyRingName = "my-key-ring" + testDescription = "my-description" +) + +// Flags +func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]string { + flagValues := map[string]string{ + globalflags.ProjectIdFlag: testProjectId, + globalflags.RegionFlag: testRegion, + keyRingNameFlag: testKeyRingName, + descriptionFlag: testDescription, + } + for _, mod := range mods { + mod(flagValues) + } + return flagValues +} + +// Input Model +func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { + model := &inputModel{ + GlobalFlagModel: &globalflags.GlobalFlagModel{ + ProjectId: testProjectId, + Region: testRegion, + Verbosity: globalflags.VerbosityDefault, + }, + KeyringName: testKeyRingName, + Description: testDescription, + } + for _, mod := range mods { + mod(model) + } + return model +} + +// Request +func fixtureRequest(mods ...func(request *kms.ApiCreateKeyRingRequest)) kms.ApiCreateKeyRingRequest { + request := testClient.CreateKeyRing(testCtx, testProjectId, testRegion) + request = request.CreateKeyRingPayload(kms.CreateKeyRingPayload{ + DisplayName: utils.Ptr(testKeyRingName), + Description: utils.Ptr(testDescription), + }) + + for _, mod := range mods { + mod(&request) + } + return request +} + +func TestParseInput(t *testing.T) { + tests := []struct { + description string + flagValues map[string]string + isValid bool + expectedModel *inputModel + }{ + { + description: "base", + flagValues: fixtureFlagValues(), + isValid: true, + expectedModel: fixtureInputModel(), + }, + { + description: "optional flags omitted", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, descriptionFlag) + }), + isValid: true, + expectedModel: fixtureInputModel(func(model *inputModel) { + model.Description = "" + }), + }, + { + description: "no values provided", + flagValues: map[string]string{}, + isValid: false, + }, + { + description: "project id missing", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, globalflags.ProjectIdFlag) + }), + isValid: false, + }, + { + description: "project id invalid 1", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[globalflags.ProjectIdFlag] = "" + }), + isValid: false, + }, + { + description: "project id invalid 2", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[globalflags.ProjectIdFlag] = "invalid-uuid" + }), + isValid: false, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + cmd := &cobra.Command{} + err := globalflags.Configure(cmd.Flags()) + if err != nil { + t.Fatalf("configure global flags: %v", err) + } + + configureFlags(cmd) + + 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) + } + } + + err = cmd.ValidateRequiredFlags() + if err != nil { + if !tt.isValid { + return + } + t.Fatalf("error validating flags: %v", err) + } + + p := print.NewPrinter() + model, err := parseInput(p, cmd) + 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(tt.expectedModel, model) + if diff != "" { + t.Fatalf("Data does not match: %s", diff) + } + }) + } +} + +func TestBuildRequest(t *testing.T) { + tests := []struct { + description string + model *inputModel + expectedRequest kms.ApiCreateKeyRingRequest + }{ + { + description: "base case", + model: fixtureInputModel(), + expectedRequest: fixtureRequest(), + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + request, err := buildRequest(testCtx, tt.model, testClient) + if err != nil { + t.Fatalf("error building request: %v", err) + } + + diff := cmp.Diff(tt.expectedRequest, request, + cmp.AllowUnexported(tt.expectedRequest), + cmpopts.EquateComparable(testCtx), + ) + if diff != "" { + t.Fatalf("Data does not match: %s", diff) + } + }) + } +} + +func TestOutputResult(t *testing.T) { + tests := []struct { + description string + keyRing *kms.KeyRing + outputFormat string + projectLabel string + wantErr bool + }{ + { + description: "nil response", + keyRing: nil, + wantErr: true, + }, + { + description: "default output", + keyRing: &kms.KeyRing{}, + projectLabel: "my-project", + wantErr: false, + }, + { + description: "json output", + keyRing: &kms.KeyRing{}, + outputFormat: print.JSONOutputFormat, + wantErr: false, + }, + { + description: "yaml output", + keyRing: &kms.KeyRing{}, + outputFormat: print.YAMLOutputFormat, + wantErr: false, + }, + } + + p := print.NewPrinter() + p.Cmd = NewCmd(¶ms.CmdParams{Printer: p}) + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + err := outputResult(p, tt.outputFormat, tt.projectLabel, tt.keyRing) + if (err != nil) != tt.wantErr { + t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/internal/cmd/beta/kms/keyring/delete/delete.go b/internal/cmd/beta/kms/keyring/delete/delete.go index e1d9d1c9a..55049d083 100644 --- a/internal/cmd/beta/kms/keyring/delete/delete.go +++ b/internal/cmd/beta/kms/keyring/delete/delete.go @@ -24,7 +24,7 @@ const ( type inputModel struct { *globalflags.GlobalFlagModel - keyRingId string + KeyRingId string } func NewCmd(params *params.CmdParams) *cobra.Command { @@ -51,10 +51,10 @@ func NewCmd(params *params.CmdParams) *cobra.Command { return err } - keyRingLabel, err := kmsUtils.GetKeyRingName(ctx, apiClient, model.ProjectId, model.keyRingId, model.Region) + keyRingLabel, err := kmsUtils.GetKeyRingName(ctx, apiClient, model.ProjectId, model.KeyRingId, model.Region) if err != nil { params.Printer.Debug(print.ErrorLevel, "get key ring name: %v", err) - keyRingLabel = model.keyRingId + keyRingLabel = model.KeyRingId } if !model.AssumeYes { @@ -91,7 +91,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu model := inputModel{ GlobalFlagModel: globalFlags, - keyRingId: keyRingId, + KeyRingId: keyRingId, } if p.IsVerbosityDebug() { @@ -107,6 +107,6 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu } func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClient) kms.ApiDeleteKeyRingRequest { - req := apiClient.DeleteKeyRing(ctx, model.ProjectId, model.Region, model.keyRingId) + req := apiClient.DeleteKeyRing(ctx, model.ProjectId, model.Region, model.KeyRingId) return req } diff --git a/internal/cmd/beta/kms/keyring/delete/delete_test.go b/internal/cmd/beta/kms/keyring/delete/delete_test.go new file mode 100644 index 000000000..c53e7d7f0 --- /dev/null +++ b/internal/cmd/beta/kms/keyring/delete/delete_test.go @@ -0,0 +1,212 @@ +package delete + +import ( + "context" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/google/uuid" + "github.com/stackitcloud/stackit-cli/internal/cmd/params" + "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" + "github.com/stackitcloud/stackit-cli/internal/pkg/print" + "github.com/stackitcloud/stackit-sdk-go/services/kms" +) + +const ( + testRegion = "eu01" +) + +type testCtxKey struct{} + +var ( + testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") + testClient = &kms.APIClient{} + testProjectId = uuid.NewString() + testKeyRingId = uuid.NewString() +) + +// Args +func fixtureArgValues(mods ...func(argValues []string)) []string { + argValues := []string{ + testKeyRingId, + } + for _, mod := range mods { + mod(argValues) + } + return argValues +} + +// Flags +func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]string { + flagValues := map[string]string{ + globalflags.ProjectIdFlag: testProjectId, + globalflags.RegionFlag: testRegion, + } + for _, mod := range mods { + mod(flagValues) + } + return flagValues +} + +// Input Model +func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { + model := &inputModel{ + GlobalFlagModel: &globalflags.GlobalFlagModel{ + ProjectId: testProjectId, + Region: testRegion, + Verbosity: globalflags.VerbosityDefault, + }, + KeyRingId: testKeyRingId, + } + for _, mod := range mods { + mod(model) + } + return model +} + +// Request +func fixtureRequest(mods ...func(request *kms.ApiDeleteKeyRingRequest)) kms.ApiDeleteKeyRingRequest { + request := testClient.DeleteKeyRing(testCtx, testProjectId, testRegion, testKeyRingId) + for _, mod := range mods { + mod(&request) + } + return request +} + +func TestParseInput(t *testing.T) { + tests := []struct { + description string + argValues []string + flagValues map[string]string + isValid bool + expectedModel *inputModel + }{ + { + description: "base", + argValues: fixtureArgValues(), + flagValues: fixtureFlagValues(), + isValid: true, + expectedModel: fixtureInputModel(), + }, + { + description: "no args (keyRingId)", + argValues: []string{}, + flagValues: fixtureFlagValues(), + isValid: false, + }, + { + description: "invalid keyRingId", + argValues: fixtureArgValues(func(argValues []string) { + argValues[0] = "Not an uuid" + }), + flagValues: fixtureFlagValues(), + isValid: false, + }, + { + description: "project id missing", + argValues: fixtureArgValues(), + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, globalflags.ProjectIdFlag) + }), + isValid: false, + }, + { + description: "project id invalid 1", + argValues: fixtureArgValues(), + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[globalflags.ProjectIdFlag] = "" + }), + isValid: false, + }, + { + description: "project id invalid 2", + argValues: fixtureArgValues(), + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[globalflags.ProjectIdFlag] = "invalid-uuid" + }), + isValid: false, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + p := print.NewPrinter() + cmd := NewCmd(¶ms.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) + } + } + + 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(tt.expectedModel, model) + if diff != "" { + t.Fatalf("Data does not match: %s", diff) + } + }) + } +} + +func TestBuildRequest(t *testing.T) { + tests := []struct { + description string + model *inputModel + expectedRequest kms.ApiDeleteKeyRingRequest + }{ + { + description: "base case", + model: fixtureInputModel(), + expectedRequest: fixtureRequest(), + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + request := buildRequest(testCtx, tt.model, testClient) + + diff := cmp.Diff(tt.expectedRequest, request, + cmp.AllowUnexported(tt.expectedRequest), + cmpopts.EquateComparable(testCtx), + ) + if diff != "" { + t.Fatalf("Data does not match: %s", diff) + } + }) + } +} diff --git a/internal/cmd/beta/kms/keyring/list/list_test.go b/internal/cmd/beta/kms/keyring/list/list_test.go new file mode 100644 index 000000000..30dad9d2c --- /dev/null +++ b/internal/cmd/beta/kms/keyring/list/list_test.go @@ -0,0 +1,211 @@ +package list + +import ( + "context" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/google/uuid" + "github.com/spf13/cobra" + "github.com/stackitcloud/stackit-cli/internal/cmd/params" + "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" + "github.com/stackitcloud/stackit-cli/internal/pkg/print" + "github.com/stackitcloud/stackit-sdk-go/services/kms" +) + +const ( + testRegion = "eu01" +) + +type testCtxKey struct{} + +var ( + testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") + testClient = &kms.APIClient{} + testProjectId = uuid.NewString() +) + +// Flags +func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]string { + flagValues := map[string]string{ + globalflags.ProjectIdFlag: testProjectId, + globalflags.RegionFlag: testRegion, + } + for _, mod := range mods { + mod(flagValues) + } + return flagValues +} + +// Input Model +func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { + model := &inputModel{ + GlobalFlagModel: &globalflags.GlobalFlagModel{ + ProjectId: testProjectId, + Region: testRegion, + Verbosity: globalflags.VerbosityDefault, + }, + } + for _, mod := range mods { + mod(model) + } + return model +} + +// Request +func fixtureRequest(mods ...func(request *kms.ApiListKeyRingsRequest)) kms.ApiListKeyRingsRequest { + request := testClient.ListKeyRings(testCtx, testProjectId, testRegion) + for _, mod := range mods { + mod(&request) + } + return request +} + +func TestParseInput(t *testing.T) { + tests := []struct { + description string + flagValues map[string]string + isValid bool + expectedModel *inputModel + }{ + { + description: "base", + flagValues: fixtureFlagValues(), + isValid: true, + expectedModel: fixtureInputModel(), + }, + { + description: "no values provided", + flagValues: map[string]string{}, + isValid: false, + }, + { + description: "project id invalid 1", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[globalflags.ProjectIdFlag] = "" + }), + isValid: false, + }, + { + description: "project id invalid 2", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[globalflags.ProjectIdFlag] = "invalid-uuid" + }), + isValid: false, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + cmd := &cobra.Command{} + 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) + } + } + + err = cmd.ValidateRequiredFlags() + if err != nil { + if !tt.isValid { + return + } + t.Fatalf("error validating flags: %v", err) + } + + p := print.NewPrinter() + model, err := parseInput(p, cmd) + 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(tt.expectedModel, model) + if diff != "" { + t.Fatalf("Data does not match: %s", diff) + } + }) + } +} + +func TestBuildRequest(t *testing.T) { + tests := []struct { + description string + model *inputModel + expectedRequest kms.ApiListKeyRingsRequest + }{ + { + description: "base case", + model: fixtureInputModel(), + expectedRequest: fixtureRequest(), + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + request := buildRequest(testCtx, tt.model, testClient) + + diff := cmp.Diff(tt.expectedRequest, request, + cmp.AllowUnexported(tt.expectedRequest), + cmpopts.EquateComparable(testCtx), + ) + if diff != "" { + t.Fatalf("Data does not match: %s", diff) + } + }) + } +} + +func TestOutputResult(t *testing.T) { + tests := []struct { + description string + keyRings []kms.KeyRing + outputFormat string + projectLabel string + wantErr bool + }{ + { + description: "default output", + keyRings: []kms.KeyRing{}, + projectLabel: "my-project", + wantErr: false, + }, + { + description: "json output", + keyRings: []kms.KeyRing{}, + outputFormat: print.JSONOutputFormat, + wantErr: false, + }, + { + description: "yaml output", + keyRings: []kms.KeyRing{}, + outputFormat: print.YAMLOutputFormat, + wantErr: false, + }, + } + + p := print.NewPrinter() + p.Cmd = NewCmd(¶ms.CmdParams{Printer: p}) + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + err := outputResult(p, tt.outputFormat, tt.keyRings) + if (err != nil) != tt.wantErr { + t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/internal/cmd/beta/kms/version/destroy/destroy_test.go b/internal/cmd/beta/kms/version/destroy/destroy_test.go new file mode 100644 index 000000000..65efb6ddd --- /dev/null +++ b/internal/cmd/beta/kms/version/destroy/destroy_test.go @@ -0,0 +1,252 @@ +package destroy + +import ( + "context" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/google/uuid" + "github.com/spf13/cobra" + "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" + "github.com/stackitcloud/stackit-cli/internal/pkg/print" + "github.com/stackitcloud/stackit-cli/internal/pkg/utils" + "github.com/stackitcloud/stackit-sdk-go/services/kms" +) + +const ( + testRegion = "eu02" +) + +type testCtxKey struct{} + +var ( + testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") + testClient = &kms.APIClient{} + testProjectId = uuid.NewString() + testKeyRingId = uuid.NewString() + testKeyId = uuid.NewString() + testVersionNumber = int64(1) +) + +// Flags +func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]string { + flagValues := map[string]string{ + globalflags.ProjectIdFlag: testProjectId, + globalflags.RegionFlag: testRegion, + keyRingIdFlag: testKeyRingId, + keyIdFlag: testKeyId, + versionNumberFlag: "1", + } + for _, mod := range mods { + mod(flagValues) + } + return flagValues +} + +// Input Model +func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { + model := &inputModel{ + GlobalFlagModel: &globalflags.GlobalFlagModel{ + ProjectId: testProjectId, + Region: testRegion, + Verbosity: globalflags.VerbosityDefault, + }, + KeyRingId: testKeyRingId, + KeyId: testKeyId, + VersionNumber: utils.Ptr(testVersionNumber), + } + for _, mod := range mods { + mod(model) + } + return model +} + +// Request +func fixtureRequest(mods ...func(request *kms.ApiDestroyVersionRequest)) kms.ApiDestroyVersionRequest { + request := testClient.DestroyVersion(testCtx, testProjectId, testRegion, testKeyRingId, testKeyId, testVersionNumber) + for _, mod := range mods { + mod(&request) + } + return request +} + +func TestParseInput(t *testing.T) { + tests := []struct { + description string + flagValues map[string]string + isValid bool + expectedModel *inputModel + }{ + { + description: "base", + flagValues: fixtureFlagValues(), + expectedModel: fixtureInputModel(), + isValid: true, + }, + { + description: "no values", + flagValues: map[string]string{}, + isValid: false, + }, + { + description: "project id missing", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, globalflags.ProjectIdFlag) + }), + isValid: false, + }, + { + description: "project id invalid 1", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[globalflags.ProjectIdFlag] = "" + }), + isValid: false, + }, + { + description: "project id invalid 2", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[globalflags.ProjectIdFlag] = "invalid-uuid" + }), + isValid: false, + }, + { + description: "key ring id missing", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, keyRingIdFlag) + }), + isValid: false, + }, + { + description: "key ring id invalid 1", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyRingIdFlag] = "" + }), + isValid: false, + }, + { + description: "key ring id invalid 2", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyRingIdFlag] = "invalid-uuid" + }), + isValid: false, + }, + { + description: "key id missing", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, keyIdFlag) + }), + isValid: false, + }, + { + description: "key id invalid 1", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyIdFlag] = "" + }), + isValid: false, + }, + { + description: "key id invalid 2", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyIdFlag] = "invalid-uuid" + }), + isValid: false, + }, + { + description: "version number missing", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, versionNumberFlag) + }), + isValid: false, + }, + { + description: "version number invalid 1", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyIdFlag] = "" + }), + isValid: false, + }, + { + description: "version number invalid 2", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyIdFlag] = "invalid-number" + }), + isValid: false, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + cmd := &cobra.Command{} + err := globalflags.Configure(cmd.Flags()) + if err != nil { + t.Fatalf("configure global flags: %v", err) + } + + configureFlags(cmd) + + 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) + } + } + + err = cmd.ValidateRequiredFlags() + if err != nil { + if !tt.isValid { + return + } + t.Fatalf("error validating flags: %v", err) + } + + p := print.NewPrinter() + model, err := parseInput(p, cmd) + 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(tt.expectedModel, model) + if diff != "" { + t.Fatalf("Data does not match: %s", diff) + } + }) + } +} + +func TestBuildRequest(t *testing.T) { + tests := []struct { + description string + model *inputModel + expectedRequest kms.ApiDestroyVersionRequest + }{ + { + description: "base case", + model: fixtureInputModel(), + expectedRequest: fixtureRequest(), + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + request := buildRequest(testCtx, tt.model, testClient) + + diff := cmp.Diff(request, tt.expectedRequest, + cmp.AllowUnexported(tt.expectedRequest), + cmpopts.EquateComparable(testCtx), + ) + if diff != "" { + t.Fatalf("Data does not match: %s", diff) + } + }) + } +} diff --git a/internal/cmd/beta/kms/version/disable/disable_test.go b/internal/cmd/beta/kms/version/disable/disable_test.go new file mode 100644 index 000000000..32f651c74 --- /dev/null +++ b/internal/cmd/beta/kms/version/disable/disable_test.go @@ -0,0 +1,252 @@ +package disable + +import ( + "context" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/google/uuid" + "github.com/spf13/cobra" + "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" + "github.com/stackitcloud/stackit-cli/internal/pkg/print" + "github.com/stackitcloud/stackit-cli/internal/pkg/utils" + "github.com/stackitcloud/stackit-sdk-go/services/kms" +) + +const ( + testRegion = "eu02" +) + +type testCtxKey struct{} + +var ( + testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") + testClient = &kms.APIClient{} + testProjectId = uuid.NewString() + testKeyRingId = uuid.NewString() + testKeyId = uuid.NewString() + testVersionNumber = int64(1) +) + +// Flags +func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]string { + flagValues := map[string]string{ + globalflags.ProjectIdFlag: testProjectId, + globalflags.RegionFlag: testRegion, + keyRingIdFlag: testKeyRingId, + keyIdFlag: testKeyId, + versionNumberFlag: "1", + } + for _, mod := range mods { + mod(flagValues) + } + return flagValues +} + +// Input Model +func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { + model := &inputModel{ + GlobalFlagModel: &globalflags.GlobalFlagModel{ + ProjectId: testProjectId, + Region: testRegion, + Verbosity: globalflags.VerbosityDefault, + }, + KeyRingId: testKeyRingId, + KeyId: testKeyId, + VersionNumber: utils.Ptr(testVersionNumber), + } + for _, mod := range mods { + mod(model) + } + return model +} + +// Request +func fixtureRequest(mods ...func(request *kms.ApiDisableVersionRequest)) kms.ApiDisableVersionRequest { + request := testClient.DisableVersion(testCtx, testProjectId, testRegion, testKeyRingId, testKeyId, testVersionNumber) + for _, mod := range mods { + mod(&request) + } + return request +} + +func TestParseInput(t *testing.T) { + tests := []struct { + description string + flagValues map[string]string + isValid bool + expectedModel *inputModel + }{ + { + description: "base", + flagValues: fixtureFlagValues(), + expectedModel: fixtureInputModel(), + isValid: true, + }, + { + description: "no values", + flagValues: map[string]string{}, + isValid: false, + }, + { + description: "project id missing", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, globalflags.ProjectIdFlag) + }), + isValid: false, + }, + { + description: "project id invalid 1", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[globalflags.ProjectIdFlag] = "" + }), + isValid: false, + }, + { + description: "project id invalid 2", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[globalflags.ProjectIdFlag] = "invalid-uuid" + }), + isValid: false, + }, + { + description: "key ring id missing", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, keyRingIdFlag) + }), + isValid: false, + }, + { + description: "key ring id invalid 1", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyRingIdFlag] = "" + }), + isValid: false, + }, + { + description: "key ring id invalid 2", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyRingIdFlag] = "invalid-uuid" + }), + isValid: false, + }, + { + description: "key id missing", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, keyIdFlag) + }), + isValid: false, + }, + { + description: "key id invalid 1", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyIdFlag] = "" + }), + isValid: false, + }, + { + description: "key id invalid 2", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyIdFlag] = "invalid-uuid" + }), + isValid: false, + }, + { + description: "version number missing", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, versionNumberFlag) + }), + isValid: false, + }, + { + description: "version number invalid 1", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyIdFlag] = "" + }), + isValid: false, + }, + { + description: "version number invalid 2", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyIdFlag] = "invalid-number" + }), + isValid: false, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + cmd := &cobra.Command{} + err := globalflags.Configure(cmd.Flags()) + if err != nil { + t.Fatalf("configure global flags: %v", err) + } + + configureFlags(cmd) + + 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) + } + } + + err = cmd.ValidateRequiredFlags() + if err != nil { + if !tt.isValid { + return + } + t.Fatalf("error validating flags: %v", err) + } + + p := print.NewPrinter() + model, err := parseInput(p, cmd) + 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(tt.expectedModel, model) + if diff != "" { + t.Fatalf("Data does not match: %s", diff) + } + }) + } +} + +func TestBuildRequest(t *testing.T) { + tests := []struct { + description string + model *inputModel + expectedRequest kms.ApiDisableVersionRequest + }{ + { + description: "base case", + model: fixtureInputModel(), + expectedRequest: fixtureRequest(), + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + request := buildRequest(testCtx, tt.model, testClient) + + diff := cmp.Diff(request, tt.expectedRequest, + cmp.AllowUnexported(tt.expectedRequest), + cmpopts.EquateComparable(testCtx), + ) + if diff != "" { + t.Fatalf("Data does not match: %s", diff) + } + }) + } +} diff --git a/internal/cmd/beta/kms/version/enable/enable_test.go b/internal/cmd/beta/kms/version/enable/enable_test.go new file mode 100644 index 000000000..70a30c67f --- /dev/null +++ b/internal/cmd/beta/kms/version/enable/enable_test.go @@ -0,0 +1,252 @@ +package enable + +import ( + "context" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/google/uuid" + "github.com/spf13/cobra" + "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" + "github.com/stackitcloud/stackit-cli/internal/pkg/print" + "github.com/stackitcloud/stackit-cli/internal/pkg/utils" + "github.com/stackitcloud/stackit-sdk-go/services/kms" +) + +const ( + testRegion = "eu02" +) + +type testCtxKey struct{} + +var ( + testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") + testClient = &kms.APIClient{} + testProjectId = uuid.NewString() + testKeyRingId = uuid.NewString() + testKeyId = uuid.NewString() + testVersionNumber = int64(1) +) + +// Flags +func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]string { + flagValues := map[string]string{ + globalflags.ProjectIdFlag: testProjectId, + globalflags.RegionFlag: testRegion, + keyRingIdFlag: testKeyRingId, + keyIdFlag: testKeyId, + versionNumberFlag: "1", + } + for _, mod := range mods { + mod(flagValues) + } + return flagValues +} + +// Input Model +func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { + model := &inputModel{ + GlobalFlagModel: &globalflags.GlobalFlagModel{ + ProjectId: testProjectId, + Region: testRegion, + Verbosity: globalflags.VerbosityDefault, + }, + KeyRingId: testKeyRingId, + KeyId: testKeyId, + VersionNumber: utils.Ptr(testVersionNumber), + } + for _, mod := range mods { + mod(model) + } + return model +} + +// Request +func fixtureRequest(mods ...func(request *kms.ApiEnableVersionRequest)) kms.ApiEnableVersionRequest { + request := testClient.EnableVersion(testCtx, testProjectId, testRegion, testKeyRingId, testKeyId, testVersionNumber) + for _, mod := range mods { + mod(&request) + } + return request +} + +func TestParseInput(t *testing.T) { + tests := []struct { + description string + flagValues map[string]string + isValid bool + expectedModel *inputModel + }{ + { + description: "base", + flagValues: fixtureFlagValues(), + expectedModel: fixtureInputModel(), + isValid: true, + }, + { + description: "no values", + flagValues: map[string]string{}, + isValid: false, + }, + { + description: "project id missing", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, globalflags.ProjectIdFlag) + }), + isValid: false, + }, + { + description: "project id invalid 1", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[globalflags.ProjectIdFlag] = "" + }), + isValid: false, + }, + { + description: "project id invalid 2", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[globalflags.ProjectIdFlag] = "invalid-uuid" + }), + isValid: false, + }, + { + description: "key ring id missing", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, keyRingIdFlag) + }), + isValid: false, + }, + { + description: "key ring id invalid 1", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyRingIdFlag] = "" + }), + isValid: false, + }, + { + description: "key ring id invalid 2", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyRingIdFlag] = "invalid-uuid" + }), + isValid: false, + }, + { + description: "key id missing", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, keyIdFlag) + }), + isValid: false, + }, + { + description: "key id invalid 1", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyIdFlag] = "" + }), + isValid: false, + }, + { + description: "key id invalid 2", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyIdFlag] = "invalid-uuid" + }), + isValid: false, + }, + { + description: "version number missing", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, versionNumberFlag) + }), + isValid: false, + }, + { + description: "version number invalid 1", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyIdFlag] = "" + }), + isValid: false, + }, + { + description: "version number invalid 2", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyIdFlag] = "invalid-number" + }), + isValid: false, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + cmd := &cobra.Command{} + err := globalflags.Configure(cmd.Flags()) + if err != nil { + t.Fatalf("configure global flags: %v", err) + } + + configureFlags(cmd) + + 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) + } + } + + err = cmd.ValidateRequiredFlags() + if err != nil { + if !tt.isValid { + return + } + t.Fatalf("error validating flags: %v", err) + } + + p := print.NewPrinter() + model, err := parseInput(p, cmd) + 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(tt.expectedModel, model) + if diff != "" { + t.Fatalf("Data does not match: %s", diff) + } + }) + } +} + +func TestBuildRequest(t *testing.T) { + tests := []struct { + description string + model *inputModel + expectedRequest kms.ApiEnableVersionRequest + }{ + { + description: "base case", + model: fixtureInputModel(), + expectedRequest: fixtureRequest(), + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + request := buildRequest(testCtx, tt.model, testClient) + + diff := cmp.Diff(request, tt.expectedRequest, + cmp.AllowUnexported(tt.expectedRequest), + cmpopts.EquateComparable(testCtx), + ) + if diff != "" { + t.Fatalf("Data does not match: %s", diff) + } + }) + } +} diff --git a/internal/cmd/beta/kms/version/list/list_test.go b/internal/cmd/beta/kms/version/list/list_test.go new file mode 100644 index 000000000..443002d35 --- /dev/null +++ b/internal/cmd/beta/kms/version/list/list_test.go @@ -0,0 +1,268 @@ +package list + +import ( + "context" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/google/uuid" + "github.com/spf13/cobra" + "github.com/stackitcloud/stackit-cli/internal/cmd/params" + "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" + "github.com/stackitcloud/stackit-cli/internal/pkg/print" + "github.com/stackitcloud/stackit-sdk-go/services/kms" +) + +const ( + testRegion = "eu02" +) + +type testCtxKey struct{} + +var ( + testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") + testClient = &kms.APIClient{} + testProjectId = uuid.NewString() + testKeyRingId = uuid.NewString() + testKeyId = uuid.NewString() +) + +// Flags +func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]string { + flagValues := map[string]string{ + globalflags.ProjectIdFlag: testProjectId, + globalflags.RegionFlag: testRegion, + keyRingIdFlag: testKeyRingId, + keyIdFlag: testKeyId, + } + for _, mod := range mods { + mod(flagValues) + } + return flagValues +} + +// Input Model +func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { + model := &inputModel{ + GlobalFlagModel: &globalflags.GlobalFlagModel{ + ProjectId: testProjectId, + Region: testRegion, + Verbosity: globalflags.VerbosityDefault, + }, + KeyRingId: testKeyRingId, + KeyId: testKeyId, + } + for _, mod := range mods { + mod(model) + } + return model +} + +// Request +func fixtureRequest(mods ...func(request *kms.ApiListVersionsRequest)) kms.ApiListVersionsRequest { + request := testClient.ListVersions(testCtx, testProjectId, testRegion, testKeyRingId, testKeyId) + for _, mod := range mods { + mod(&request) + } + return request +} + +func TestParseInput(t *testing.T) { + tests := []struct { + description string + flagValues map[string]string + isValid bool + expectedModel *inputModel + }{ + { + description: "base", + flagValues: fixtureFlagValues(), + expectedModel: fixtureInputModel(), + isValid: true, + }, + { + description: "no values", + flagValues: map[string]string{}, + isValid: false, + }, + { + description: "project id missing", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, globalflags.ProjectIdFlag) + }), + isValid: false, + }, + { + description: "project id invalid 1", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[globalflags.ProjectIdFlag] = "" + }), + isValid: false, + }, + { + description: "project id invalid 2", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[globalflags.ProjectIdFlag] = "invalid-uuid" + }), + isValid: false, + }, + { + description: "key ring id missing", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, keyRingIdFlag) + }), + isValid: false, + }, + { + description: "key ring id invalid 1", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyRingIdFlag] = "" + }), + isValid: false, + }, + { + description: "key ring id invalid 2", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyRingIdFlag] = "invalid-uuid" + }), + isValid: false, + }, + { + description: "key id missing", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, keyIdFlag) + }), + isValid: false, + }, + { + description: "key id invalid 1", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyIdFlag] = "" + }), + isValid: false, + }, + { + description: "key id invalid 2", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyIdFlag] = "invalid-uuid" + }), + isValid: false, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + cmd := &cobra.Command{} + err := globalflags.Configure(cmd.Flags()) + if err != nil { + t.Fatalf("configure global flags: %v", err) + } + + configureFlags(cmd) + + 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) + } + } + + err = cmd.ValidateRequiredFlags() + if err != nil { + if !tt.isValid { + return + } + t.Fatalf("error validating flags: %v", err) + } + + p := print.NewPrinter() + model, err := parseInput(p, cmd) + 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(tt.expectedModel, model) + if diff != "" { + t.Fatalf("Data does not match: %s", diff) + } + }) + } +} + +func TestBuildRequest(t *testing.T) { + tests := []struct { + description string + model *inputModel + expectedRequest kms.ApiListVersionsRequest + }{ + { + description: "base case", + model: fixtureInputModel(), + expectedRequest: fixtureRequest(), + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + request := buildRequest(testCtx, tt.model, testClient) + + diff := cmp.Diff(request, tt.expectedRequest, + cmp.AllowUnexported(tt.expectedRequest), + cmpopts.EquateComparable(testCtx), + ) + if diff != "" { + t.Fatalf("Data does not match: %s", diff) + } + }) + } +} + +func TestOutputResult(t *testing.T) { + tests := []struct { + description string + versions []kms.Version + outputFormat string + projectLabel string + wantErr bool + }{ + { + description: "default output", + versions: []kms.Version{}, + projectLabel: "my-project", + wantErr: false, + }, + { + description: "json output", + versions: []kms.Version{}, + outputFormat: print.JSONOutputFormat, + wantErr: false, + }, + { + description: "yaml output", + versions: []kms.Version{}, + outputFormat: print.YAMLOutputFormat, + wantErr: false, + }, + } + + p := print.NewPrinter() + p.Cmd = NewCmd(¶ms.CmdParams{Printer: p}) + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + err := outputResult(p, tt.outputFormat, tt.versions) + if (err != nil) != tt.wantErr { + t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/internal/cmd/beta/kms/version/restore/restore_test.go b/internal/cmd/beta/kms/version/restore/restore_test.go new file mode 100644 index 000000000..719bebf67 --- /dev/null +++ b/internal/cmd/beta/kms/version/restore/restore_test.go @@ -0,0 +1,252 @@ +package restore + +import ( + "context" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/google/uuid" + "github.com/spf13/cobra" + "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" + "github.com/stackitcloud/stackit-cli/internal/pkg/print" + "github.com/stackitcloud/stackit-cli/internal/pkg/utils" + "github.com/stackitcloud/stackit-sdk-go/services/kms" +) + +const ( + testRegion = "eu02" +) + +type testCtxKey struct{} + +var ( + testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") + testClient = &kms.APIClient{} + testProjectId = uuid.NewString() + testKeyRingId = uuid.NewString() + testKeyId = uuid.NewString() + testVersionNumber = int64(1) +) + +// Flags +func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]string { + flagValues := map[string]string{ + globalflags.ProjectIdFlag: testProjectId, + globalflags.RegionFlag: testRegion, + keyRingIdFlag: testKeyRingId, + keyIdFlag: testKeyId, + versionNumberFlag: "1", + } + for _, mod := range mods { + mod(flagValues) + } + return flagValues +} + +// Input Model +func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { + model := &inputModel{ + GlobalFlagModel: &globalflags.GlobalFlagModel{ + ProjectId: testProjectId, + Region: testRegion, + Verbosity: globalflags.VerbosityDefault, + }, + KeyRingId: testKeyRingId, + KeyId: testKeyId, + VersionNumber: utils.Ptr(testVersionNumber), + } + for _, mod := range mods { + mod(model) + } + return model +} + +// Request +func fixtureRequest(mods ...func(request *kms.ApiRestoreVersionRequest)) kms.ApiRestoreVersionRequest { + request := testClient.RestoreVersion(testCtx, testProjectId, testRegion, testKeyRingId, testKeyId, testVersionNumber) + for _, mod := range mods { + mod(&request) + } + return request +} + +func TestParseInput(t *testing.T) { + tests := []struct { + description string + flagValues map[string]string + isValid bool + expectedModel *inputModel + }{ + { + description: "base", + flagValues: fixtureFlagValues(), + expectedModel: fixtureInputModel(), + isValid: true, + }, + { + description: "no values", + flagValues: map[string]string{}, + isValid: false, + }, + { + description: "project id missing", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, globalflags.ProjectIdFlag) + }), + isValid: false, + }, + { + description: "project id invalid 1", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[globalflags.ProjectIdFlag] = "" + }), + isValid: false, + }, + { + description: "project id invalid 2", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[globalflags.ProjectIdFlag] = "invalid-uuid" + }), + isValid: false, + }, + { + description: "key ring id missing", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, keyRingIdFlag) + }), + isValid: false, + }, + { + description: "key ring id invalid 1", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyRingIdFlag] = "" + }), + isValid: false, + }, + { + description: "key ring id invalid 2", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyRingIdFlag] = "invalid-uuid" + }), + isValid: false, + }, + { + description: "key id missing", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, keyIdFlag) + }), + isValid: false, + }, + { + description: "key id invalid 1", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyIdFlag] = "" + }), + isValid: false, + }, + { + description: "key id invalid 2", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyIdFlag] = "invalid-uuid" + }), + isValid: false, + }, + { + description: "version number missing", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, versionNumberFlag) + }), + isValid: false, + }, + { + description: "version number invalid 1", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyIdFlag] = "" + }), + isValid: false, + }, + { + description: "version number invalid 2", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyIdFlag] = "invalid-number" + }), + isValid: false, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + cmd := &cobra.Command{} + err := globalflags.Configure(cmd.Flags()) + if err != nil { + t.Fatalf("configure global flags: %v", err) + } + + configureFlags(cmd) + + 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) + } + } + + err = cmd.ValidateRequiredFlags() + if err != nil { + if !tt.isValid { + return + } + t.Fatalf("error validating flags: %v", err) + } + + p := print.NewPrinter() + model, err := parseInput(p, cmd) + 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(tt.expectedModel, model) + if diff != "" { + t.Fatalf("Data does not match: %s", diff) + } + }) + } +} + +func TestBuildRequest(t *testing.T) { + tests := []struct { + description string + model *inputModel + expectedRequest kms.ApiRestoreVersionRequest + }{ + { + description: "base case", + model: fixtureInputModel(), + expectedRequest: fixtureRequest(), + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + request := buildRequest(testCtx, tt.model, testClient) + + diff := cmp.Diff(request, tt.expectedRequest, + cmp.AllowUnexported(tt.expectedRequest), + cmpopts.EquateComparable(testCtx), + ) + if diff != "" { + t.Fatalf("Data does not match: %s", diff) + } + }) + } +} diff --git a/internal/cmd/beta/kms/wrappingkey/create/create_test.go b/internal/cmd/beta/kms/wrappingkey/create/create_test.go new file mode 100644 index 000000000..6ae2bd384 --- /dev/null +++ b/internal/cmd/beta/kms/wrappingkey/create/create_test.go @@ -0,0 +1,314 @@ +package create + +import ( + "context" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/google/uuid" + "github.com/spf13/cobra" + "github.com/stackitcloud/stackit-cli/internal/cmd/params" + "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" + "github.com/stackitcloud/stackit-cli/internal/pkg/print" + "github.com/stackitcloud/stackit-cli/internal/pkg/utils" + "github.com/stackitcloud/stackit-sdk-go/services/kms" +) + +const ( + testRegion = "eu01" +) + +type testCtxKey struct{} + +var ( + testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") + testClient = &kms.APIClient{} + testProjectId = uuid.NewString() + testKeyRingId = uuid.NewString() + testAlgorithm = "some_rsa_2048" + testDisplayName = "my-key" + testPurpose = "asymmetric_encrypt_decrypt" + testDescription = "my key description" + testBackend = "notSoftware" +) + +// Flags +func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]string { + flagValues := map[string]string{ + globalflags.ProjectIdFlag: testProjectId, + globalflags.RegionFlag: testRegion, + keyRingIdFlag: testKeyRingId, + algorithmFlag: testAlgorithm, + displayNameFlag: testDisplayName, + purposeFlag: testPurpose, + descriptionFlag: testDescription, + backendFlag: testBackend, + } + for _, mod := range mods { + mod(flagValues) + } + return flagValues +} + +// Input Model +func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { + model := &inputModel{ + GlobalFlagModel: &globalflags.GlobalFlagModel{ + ProjectId: testProjectId, + Region: testRegion, + Verbosity: globalflags.VerbosityDefault, + }, + KeyRingId: testKeyRingId, + Algorithm: utils.Ptr(testAlgorithm), + Name: utils.Ptr(testDisplayName), + Purpose: utils.Ptr(testPurpose), + Description: utils.Ptr(testDescription), + Backend: testBackend, + } + for _, mod := range mods { + mod(model) + } + return model +} + +// Request +func fixtureRequest(mods ...func(request *kms.ApiCreateWrappingKeyRequest)) kms.ApiCreateWrappingKeyRequest { + request := testClient.CreateWrappingKey(testCtx, testProjectId, testRegion, testKeyRingId) + request = request.CreateWrappingKeyPayload(kms.CreateWrappingKeyPayload{ + Algorithm: kms.CreateWrappingKeyPayloadGetAlgorithmAttributeType(utils.Ptr(testAlgorithm)), + DisplayName: utils.Ptr(testDisplayName), + Purpose: kms.CreateWrappingKeyPayloadGetPurposeAttributeType(utils.Ptr(testPurpose)), + Description: utils.Ptr(testDescription), + Backend: kms.CreateWrappingKeyPayloadGetBackendAttributeType(utils.Ptr(testBackend)), + }) + + for _, mod := range mods { + mod(&request) + } + return request +} + +func TestParseInput(t *testing.T) { + tests := []struct { + description string + flagValues map[string]string + isValid bool + expectedModel *inputModel + }{ + { + description: "base", + flagValues: fixtureFlagValues(), + isValid: true, + expectedModel: fixtureInputModel(), + }, + { + description: "optional flags omitted", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, descriptionFlag) + delete(flagValues, backendFlag) + }), + isValid: true, + expectedModel: fixtureInputModel(func(model *inputModel) { + model.Description = nil + model.Backend = "software" + }), + }, + { + description: "no values provided", + flagValues: map[string]string{}, + isValid: false, + }, + { + description: "project id missing", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, globalflags.ProjectIdFlag) + }), + isValid: false, + }, + { + description: "project id invalid 1", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[globalflags.ProjectIdFlag] = "" + }), + isValid: false, + }, + { + description: "project id invalid 2", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[globalflags.ProjectIdFlag] = "invalid-uuid" + }), + isValid: false, + }, + { + description: "key ring id missing (required)", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, keyRingIdFlag) + }), + isValid: false, + }, + { + description: "key ring id invalid", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyRingIdFlag] = "invalid-uuid" + }), + isValid: false, + }, + { + description: "algorithm missing (required)", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, algorithmFlag) + }), + isValid: false, + }, + { + description: "name missing (required)", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, displayNameFlag) + }), + isValid: false, + }, + { + description: "purpose missing (required)", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, purposeFlag) + }), + isValid: false, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + cmd := &cobra.Command{} + err := globalflags.Configure(cmd.Flags()) + if err != nil { + t.Fatalf("configure global flags: %v", err) + } + + configureFlags(cmd) + + 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) + } + } + + err = cmd.ValidateRequiredFlags() + if err != nil { + if !tt.isValid { + return + } + t.Fatalf("error validating flags: %v", err) + } + + p := print.NewPrinter() + model, err := parseInput(p, cmd) + 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(tt.expectedModel, model) + if diff != "" { + t.Fatalf("Data does not match: %s", diff) + } + }) + } +} + +func TestBuildRequest(t *testing.T) { + tests := []struct { + description string + model *inputModel + expectedRequest kms.ApiCreateWrappingKeyRequest + }{ + { + description: "base case", + model: fixtureInputModel(), + expectedRequest: fixtureRequest(), + }, + { + description: "no optional values", + model: fixtureInputModel(func(model *inputModel) { + model.Description = nil + }), + expectedRequest: fixtureRequest().CreateWrappingKeyPayload(kms.CreateWrappingKeyPayload{ + Algorithm: kms.CreateWrappingKeyPayloadGetAlgorithmAttributeType(utils.Ptr(testAlgorithm)), + DisplayName: utils.Ptr(testDisplayName), + Purpose: kms.CreateWrappingKeyPayloadGetPurposeAttributeType(utils.Ptr(testPurpose)), + Backend: kms.CreateWrappingKeyPayloadGetBackendAttributeType(utils.Ptr(testBackend)), + }), + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + request, err := buildRequest(testCtx, tt.model, testClient) + if err != nil { + t.Fatalf("error building request: %v", err) + } + + diff := cmp.Diff(tt.expectedRequest, request, + cmp.AllowUnexported(tt.expectedRequest), + cmpopts.EquateComparable(testCtx), + ) + if diff != "" { + t.Fatalf("Data does not match: %s", diff) + } + }) + } +} + +func TestOutputResult(t *testing.T) { + tests := []struct { + description string + wrappingKey *kms.WrappingKey + outputFormat string + projectLabel string + wantErr bool + }{ + { + description: "nil response", + wrappingKey: nil, + wantErr: true, + }, + { + description: "default output", + wrappingKey: &kms.WrappingKey{}, + projectLabel: "my-project", + wantErr: false, + }, + { + description: "json output", + wrappingKey: &kms.WrappingKey{}, + outputFormat: print.JSONOutputFormat, + wantErr: false, + }, + { + description: "yaml output", + wrappingKey: &kms.WrappingKey{}, + outputFormat: print.YAMLOutputFormat, + wantErr: false, + }, + } + + p := print.NewPrinter() + p.Cmd = NewCmd(¶ms.CmdParams{Printer: p}) + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + err := outputResult(p, tt.outputFormat, tt.projectLabel, tt.wrappingKey) + if (err != nil) != tt.wantErr { + t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/internal/cmd/beta/kms/wrappingkey/delete/delete.go b/internal/cmd/beta/kms/wrappingkey/delete/delete.go index 1d2f6d37e..1f5224a0d 100644 --- a/internal/cmd/beta/kms/wrappingkey/delete/delete.go +++ b/internal/cmd/beta/kms/wrappingkey/delete/delete.go @@ -26,8 +26,8 @@ const ( type inputModel struct { *globalflags.GlobalFlagModel - keyRingId string - wrappingKey string + KeyRingId string + WrappingKey string } func NewCmd(params *params.CmdParams) *cobra.Command { @@ -54,10 +54,10 @@ func NewCmd(params *params.CmdParams) *cobra.Command { return err } - wrappingKeyName, err := kmsUtils.GetWrappingKeyName(ctx, apiClient, model.ProjectId, model.Region, model.keyRingId, model.wrappingKey) + wrappingKeyName, err := kmsUtils.GetWrappingKeyName(ctx, apiClient, model.ProjectId, model.Region, model.KeyRingId, model.WrappingKey) if err != nil { params.Printer.Debug(print.ErrorLevel, "get wrapping key name: %v", err) - wrappingKeyName = model.wrappingKey + wrappingKeyName = model.WrappingKey } if !model.AssumeYes { @@ -107,8 +107,8 @@ func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { model := inputModel{ GlobalFlagModel: globalFlags, - keyRingId: keyRingId, - wrappingKey: wrappingKeyId, + KeyRingId: keyRingId, + WrappingKey: wrappingKeyId, } if p.IsVerbosityDebug() { @@ -124,7 +124,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { } func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClient) kms.ApiDeleteWrappingKeyRequest { - req := apiClient.DeleteWrappingKey(ctx, model.ProjectId, model.Region, model.keyRingId, model.wrappingKey) + req := apiClient.DeleteWrappingKey(ctx, model.ProjectId, model.Region, model.KeyRingId, model.WrappingKey) return req } diff --git a/internal/cmd/beta/kms/wrappingkey/delete/delete_test.go b/internal/cmd/beta/kms/wrappingkey/delete/delete_test.go new file mode 100644 index 000000000..6f6b0ca7f --- /dev/null +++ b/internal/cmd/beta/kms/wrappingkey/delete/delete_test.go @@ -0,0 +1,220 @@ +package delete + +import ( + "context" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/google/uuid" + "github.com/spf13/cobra" + "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" + "github.com/stackitcloud/stackit-cli/internal/pkg/print" + "github.com/stackitcloud/stackit-sdk-go/services/kms" +) + +const ( + testRegion = "eu01" +) + +type testCtxKey struct{} + +var ( + testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") + testClient = &kms.APIClient{} + testProjectId = uuid.NewString() + testKeyRingId = uuid.NewString() + testWrappingKeyRingId = uuid.NewString() +) + +// Flags +func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]string { + flagValues := map[string]string{ + globalflags.ProjectIdFlag: testProjectId, + globalflags.RegionFlag: testRegion, + keyRingIdFlag: testKeyRingId, + wrappingKeyIdFlag: testWrappingKeyRingId, + } + for _, mod := range mods { + mod(flagValues) + } + return flagValues +} + +// Input Model +func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { + model := &inputModel{ + GlobalFlagModel: &globalflags.GlobalFlagModel{ + ProjectId: testProjectId, + Region: testRegion, + Verbosity: globalflags.VerbosityDefault, + }, + KeyRingId: testKeyRingId, + WrappingKey: testWrappingKeyRingId, + } + for _, mod := range mods { + mod(model) + } + return model +} + +// Request +func fixtureRequest(mods ...func(request *kms.ApiDeleteWrappingKeyRequest)) kms.ApiDeleteWrappingKeyRequest { + request := testClient.DeleteWrappingKey(testCtx, testProjectId, testRegion, testKeyRingId, testWrappingKeyRingId) + for _, mod := range mods { + mod(&request) + } + return request +} + +func TestParseInput(t *testing.T) { + tests := []struct { + description string + flagValues map[string]string + isValid bool + expectedModel *inputModel + }{ + { + description: "base", + flagValues: fixtureFlagValues(), + isValid: true, + expectedModel: fixtureInputModel(), + }, + { + description: "no values provided", + flagValues: map[string]string{}, + isValid: false, + }, + { + description: "project id missing", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, globalflags.ProjectIdFlag) + }), + isValid: false, + }, + { + description: "project id invalid 1", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[globalflags.ProjectIdFlag] = "" + }), + isValid: false, + }, + { + description: "project id invalid 2", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[globalflags.ProjectIdFlag] = "invalid-uuid" + }), + isValid: false, + }, + { + description: "key ring id missing (required)", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, keyRingIdFlag) + }), + isValid: false, + }, + { + description: "key ring id invalid", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyRingIdFlag] = "invalid-uuid" + }), + isValid: false, + }, + { + description: "wrapping key id missing (required)", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, wrappingKeyIdFlag) + }), + isValid: false, + }, + { + description: "wrapping key id invalid 1", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[wrappingKeyIdFlag] = "" + }), + isValid: false, + }, + { + description: "wrapping key id invalid 2", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[wrappingKeyIdFlag] = "invalid-uuid" + }), + isValid: false, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + cmd := &cobra.Command{} + err := globalflags.Configure(cmd.Flags()) + if err != nil { + t.Fatalf("configure global flags: %v", err) + } + + configureFlags(cmd) + + 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) + } + } + + err = cmd.ValidateRequiredFlags() + if err != nil { + if !tt.isValid { + return + } + t.Fatalf("error validating flags: %v", err) + } + + p := print.NewPrinter() + model, err := parseInput(p, cmd) + 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(tt.expectedModel, model) + if diff != "" { + t.Fatalf("Data does not match: %s", diff) + } + }) + } +} + +func TestBuildRequest(t *testing.T) { + tests := []struct { + description string + model *inputModel + expectedRequest kms.ApiDeleteWrappingKeyRequest + }{ + { + description: "base case", + model: fixtureInputModel(), + expectedRequest: fixtureRequest(), + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + request := buildRequest(testCtx, tt.model, testClient) + + diff := cmp.Diff(tt.expectedRequest, request, + cmp.AllowUnexported(tt.expectedRequest), + cmpopts.EquateComparable(testCtx), + ) + if diff != "" { + t.Fatalf("Data does not match: %s", diff) + } + }) + } +} diff --git a/internal/cmd/beta/kms/wrappingkey/list/list.go b/internal/cmd/beta/kms/wrappingkey/list/list.go index a0b4bb2b0..6c2163f66 100644 --- a/internal/cmd/beta/kms/wrappingkey/list/list.go +++ b/internal/cmd/beta/kms/wrappingkey/list/list.go @@ -25,7 +25,7 @@ const ( type inputModel struct { *globalflags.GlobalFlagModel - keyRingId string + KeyRingId string } func NewCmd(params *params.CmdParams) *cobra.Command { @@ -63,7 +63,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { return fmt.Errorf("get KMS Wrapping Keys: %w", err) } if resp.WrappingKeys == nil || len(*resp.WrappingKeys) == 0 { - params.Printer.Info("No Wrapping Keys found for project %q in region %q under the key ring %q\n", model.ProjectId, model.Region, model.keyRingId) + params.Printer.Info("No Wrapping Keys found for project %q in region %q under the key ring %q\n", model.ProjectId, model.Region, model.KeyRingId) return nil } wrappingKeys := *resp.WrappingKeys @@ -84,7 +84,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu model := inputModel{ GlobalFlagModel: globalFlags, - keyRingId: keyRingId, + KeyRingId: keyRingId, } if p.IsVerbosityDebug() { @@ -100,7 +100,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu } func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClient) kms.ApiListWrappingKeysRequest { - req := apiClient.ListWrappingKeys(ctx, model.ProjectId, model.Region, model.keyRingId) + req := apiClient.ListWrappingKeys(ctx, model.ProjectId, model.Region, model.KeyRingId) return req } diff --git a/internal/cmd/beta/kms/wrappingkey/list/list_test.go b/internal/cmd/beta/kms/wrappingkey/list/list_test.go new file mode 100644 index 000000000..d826546b4 --- /dev/null +++ b/internal/cmd/beta/kms/wrappingkey/list/list_test.go @@ -0,0 +1,258 @@ +package list + +import ( + "context" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/google/uuid" + "github.com/stackitcloud/stackit-cli/internal/cmd/params" + "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" + "github.com/stackitcloud/stackit-cli/internal/pkg/print" + "github.com/stackitcloud/stackit-sdk-go/services/kms" +) + +const ( + testRegion = "eu02" +) + +type testCtxKey struct{} + +var ( + testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") + testClient = &kms.APIClient{} + testProjectId = uuid.NewString() + testKeyRingId = uuid.NewString() +) + +// Args +func fixtureArgValues(mods ...func(argValues []string)) []string { + argValues := []string{ + testKeyRingId, + } + for _, mod := range mods { + mod(argValues) + } + return argValues +} + +// Flags +func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]string { + flagValues := map[string]string{ + globalflags.ProjectIdFlag: testProjectId, + globalflags.RegionFlag: testRegion, + } + for _, mod := range mods { + mod(flagValues) + } + return flagValues +} + +// Input Model +func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { + model := &inputModel{ + GlobalFlagModel: &globalflags.GlobalFlagModel{ + ProjectId: testProjectId, + Region: testRegion, + Verbosity: globalflags.VerbosityDefault, + }, + KeyRingId: testKeyRingId, + } + for _, mod := range mods { + mod(model) + } + return model +} + +// Request +func fixtureRequest(mods ...func(request *kms.ApiListWrappingKeysRequest)) kms.ApiListWrappingKeysRequest { + request := testClient.ListWrappingKeys(testCtx, testProjectId, testRegion, testKeyRingId) + for _, mod := range mods { + mod(&request) + } + return request +} + +func TestParseInput(t *testing.T) { + tests := []struct { + description string + argValues []string + flagValues map[string]string + isValid bool + expectedModel *inputModel + }{ + { + description: "base", + argValues: fixtureArgValues(), + flagValues: fixtureFlagValues(), + expectedModel: fixtureInputModel(), + isValid: true, + }, + { + description: "no args (keyRingId)", + argValues: []string{}, + flagValues: fixtureFlagValues(), + isValid: false, + }, + { + description: "invalid keyRingId", + argValues: fixtureArgValues(func(argValues []string) { + argValues[0] = "Not an uuid" + }), + flagValues: fixtureFlagValues(), + isValid: false, + }, + { + description: "no values", + argValues: fixtureArgValues(), + flagValues: map[string]string{}, + isValid: false, + }, + { + description: "project id missing", + argValues: fixtureArgValues(), + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, globalflags.ProjectIdFlag) + }), + isValid: false, + }, + { + description: "project id invalid 1", + argValues: fixtureArgValues(), + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[globalflags.ProjectIdFlag] = "" + }), + isValid: false, + }, + { + description: "project id invalid 2", + argValues: fixtureArgValues(), + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[globalflags.ProjectIdFlag] = "invalid-uuid" + }), + isValid: false, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + p := print.NewPrinter() + cmd := NewCmd(¶ms.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) + } + } + + 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(tt.expectedModel, model) + if diff != "" { + t.Fatalf("Data does not match: %s", diff) + } + }) + } +} + +func TestBuildRequest(t *testing.T) { + tests := []struct { + description string + model *inputModel + expectedRequest kms.ApiListWrappingKeysRequest + }{ + { + description: "base case", + model: fixtureInputModel(), + expectedRequest: fixtureRequest(), + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + request := buildRequest(testCtx, tt.model, testClient) + + diff := cmp.Diff(request, tt.expectedRequest, + cmp.AllowUnexported(tt.expectedRequest), + cmpopts.EquateComparable(testCtx), + ) + if diff != "" { + t.Fatalf("Data does not match: %s", diff) + } + }) + } +} + +func TestOutputResult(t *testing.T) { + tests := []struct { + description string + wrappingKeys []kms.WrappingKey + outputFormat string + projectLabel string + wantErr bool + }{ + { + description: "default output", + wrappingKeys: []kms.WrappingKey{}, + projectLabel: "my-project", + wantErr: false, + }, + { + description: "json output", + wrappingKeys: []kms.WrappingKey{}, + outputFormat: print.JSONOutputFormat, + wantErr: false, + }, + { + description: "yaml output", + wrappingKeys: []kms.WrappingKey{}, + outputFormat: print.YAMLOutputFormat, + wantErr: false, + }, + } + + p := print.NewPrinter() + p.Cmd = NewCmd(¶ms.CmdParams{Printer: p}) + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + err := outputResult(p, tt.outputFormat, tt.wrappingKeys) + if (err != nil) != tt.wantErr { + t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} From 1c4301d86ba7f4fefc5d457cd4b2795b1d05c041 Mon Sep 17 00:00:00 2001 From: Jan Sternagel Date: Sat, 23 Aug 2025 23:57:18 +0200 Subject: [PATCH 06/52] added generated documentation updates --- docs/stackit_beta.md | 1 + docs/stackit_beta_kms.md | 37 +++++++++++++++ docs/stackit_beta_kms_key.md | 39 ++++++++++++++++ docs/stackit_beta_kms_key_create.md | 50 +++++++++++++++++++++ docs/stackit_beta_kms_key_delete.md | 42 +++++++++++++++++ docs/stackit_beta_kms_key_import.md | 44 ++++++++++++++++++ docs/stackit_beta_kms_key_list.md | 43 ++++++++++++++++++ docs/stackit_beta_kms_key_restore.md | 42 +++++++++++++++++ docs/stackit_beta_kms_key_rotate.md | 42 +++++++++++++++++ docs/stackit_beta_kms_keyring.md | 36 +++++++++++++++ docs/stackit_beta_kms_keyring_create.md | 45 +++++++++++++++++++ docs/stackit_beta_kms_keyring_delete.md | 40 +++++++++++++++++ docs/stackit_beta_kms_keyring_list.md | 43 ++++++++++++++++++ docs/stackit_beta_kms_version.md | 38 ++++++++++++++++ docs/stackit_beta_kms_version_destroy.md | 43 ++++++++++++++++++ docs/stackit_beta_kms_version_disable.md | 43 ++++++++++++++++++ docs/stackit_beta_kms_version_enable.md | 43 ++++++++++++++++++ docs/stackit_beta_kms_version_list.md | 45 +++++++++++++++++++ docs/stackit_beta_kms_version_restore.md | 43 ++++++++++++++++++ docs/stackit_beta_kms_wrappingkey.md | 36 +++++++++++++++ docs/stackit_beta_kms_wrappingkey_create.md | 49 ++++++++++++++++++++ docs/stackit_beta_kms_wrappingkey_delete.md | 42 +++++++++++++++++ docs/stackit_beta_kms_wrappingkey_list.md | 43 ++++++++++++++++++ docs/stackit_config_set.md | 1 + docs/stackit_config_unset.md | 1 + 25 files changed, 931 insertions(+) create mode 100644 docs/stackit_beta_kms.md create mode 100644 docs/stackit_beta_kms_key.md create mode 100644 docs/stackit_beta_kms_key_create.md create mode 100644 docs/stackit_beta_kms_key_delete.md create mode 100644 docs/stackit_beta_kms_key_import.md create mode 100644 docs/stackit_beta_kms_key_list.md create mode 100644 docs/stackit_beta_kms_key_restore.md create mode 100644 docs/stackit_beta_kms_key_rotate.md create mode 100644 docs/stackit_beta_kms_keyring.md create mode 100644 docs/stackit_beta_kms_keyring_create.md create mode 100644 docs/stackit_beta_kms_keyring_delete.md create mode 100644 docs/stackit_beta_kms_keyring_list.md create mode 100644 docs/stackit_beta_kms_version.md create mode 100644 docs/stackit_beta_kms_version_destroy.md create mode 100644 docs/stackit_beta_kms_version_disable.md create mode 100644 docs/stackit_beta_kms_version_enable.md create mode 100644 docs/stackit_beta_kms_version_list.md create mode 100644 docs/stackit_beta_kms_version_restore.md create mode 100644 docs/stackit_beta_kms_wrappingkey.md create mode 100644 docs/stackit_beta_kms_wrappingkey_create.md create mode 100644 docs/stackit_beta_kms_wrappingkey_delete.md create mode 100644 docs/stackit_beta_kms_wrappingkey_list.md diff --git a/docs/stackit_beta.md b/docs/stackit_beta.md index b58eb067a..23097f8ca 100644 --- a/docs/stackit_beta.md +++ b/docs/stackit_beta.md @@ -42,5 +42,6 @@ stackit beta [flags] * [stackit](./stackit.md) - Manage STACKIT resources using the command line * [stackit beta alb](./stackit_beta_alb.md) - Manages application loadbalancers +* [stackit beta kms](./stackit_beta_kms.md) - Provides functionality for KMS * [stackit beta sqlserverflex](./stackit_beta_sqlserverflex.md) - Provides functionality for SQLServer Flex diff --git a/docs/stackit_beta_kms.md b/docs/stackit_beta_kms.md new file mode 100644 index 000000000..35fc5b27b --- /dev/null +++ b/docs/stackit_beta_kms.md @@ -0,0 +1,37 @@ +## stackit beta kms + +Provides functionality for KMS + +### Synopsis + +Provides functionality for KMS. + +``` +stackit beta kms [flags] +``` + +### Options + +``` + -h, --help Help for "stackit beta kms" +``` + +### Options inherited from parent commands + +``` + -y, --assume-yes If set, skips all confirmation prompts + --async If set, runs the command asynchronously + -o, --output-format string Output format, one of ["json" "pretty" "none" "yaml"] + -p, --project-id string Project ID + --region string Target region for region-specific requests + --verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info") +``` + +### SEE ALSO + +* [stackit beta](./stackit_beta.md) - Contains beta STACKIT CLI commands +* [stackit beta kms key](./stackit_beta_kms_key.md) - Manage KMS Keys +* [stackit beta kms keyring](./stackit_beta_kms_keyring.md) - Manage KMS Keyrings +* [stackit beta kms version](./stackit_beta_kms_version.md) - Manage KMS Key versions +* [stackit beta kms wrappingkey](./stackit_beta_kms_wrappingkey.md) - Manage KMS Wrapping Keys + diff --git a/docs/stackit_beta_kms_key.md b/docs/stackit_beta_kms_key.md new file mode 100644 index 000000000..84080db15 --- /dev/null +++ b/docs/stackit_beta_kms_key.md @@ -0,0 +1,39 @@ +## stackit beta kms key + +Manage KMS Keys + +### Synopsis + +Provides CRUD functionality for Key operations inside the KMS + +``` +stackit beta kms key [flags] +``` + +### Options + +``` + -h, --help Help for "stackit beta kms key" +``` + +### Options inherited from parent commands + +``` + -y, --assume-yes If set, skips all confirmation prompts + --async If set, runs the command asynchronously + -o, --output-format string Output format, one of ["json" "pretty" "none" "yaml"] + -p, --project-id string Project ID + --region string Target region for region-specific requests + --verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info") +``` + +### SEE ALSO + +* [stackit beta kms](./stackit_beta_kms.md) - Provides functionality for KMS +* [stackit beta kms key create](./stackit_beta_kms_key_create.md) - Creates a KMS Key +* [stackit beta kms key delete](./stackit_beta_kms_key_delete.md) - Deletes a KMS Key +* [stackit beta kms key import](./stackit_beta_kms_key_import.md) - Import a KMS Key Version +* [stackit beta kms key list](./stackit_beta_kms_key_list.md) - Lists all KMS Keys +* [stackit beta kms key restore](./stackit_beta_kms_key_restore.md) - Resotre a Key +* [stackit beta kms key rotate](./stackit_beta_kms_key_rotate.md) - Rotate a key + diff --git a/docs/stackit_beta_kms_key_create.md b/docs/stackit_beta_kms_key_create.md new file mode 100644 index 000000000..e28206dc6 --- /dev/null +++ b/docs/stackit_beta_kms_key_create.md @@ -0,0 +1,50 @@ +## stackit beta kms key create + +Creates a KMS Key + +### Synopsis + +Creates a KMS Key. + +``` +stackit beta kms key create [flags] +``` + +### Examples + +``` + Create a Symmetric KMS Key + $ stakit beta kms key create --key-ring "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-key-name" --purpose "symmetric_encrypt_decrypt" + + Create a Message Authentication KMS Key + $ stakit beta kms key create --key-ring "my-keyring-id" --algorithm "hmac_sha512" --name "my-key-name" --purpose "message_authentication_code" +``` + +### Options + +``` + --algorithm string En-/Decryption / signing algorithm + --backend string The backend that is responsible for maintaining this key (default "software") + --description string Optinal description of the Key + -h, --help Help for "stackit beta kms key create" + --import-only States whether versions can be created or only imported + --key-ring string ID of the KMS Key Ring + --name string The display name to distinguish multiple keys + --purpose string Purpose of the Key. Enum: 'symmetric_encrypt_decrypt', 'asymmetric_encrypt_decrypt', 'message_authentication_code', 'asymmetric_sign_verify' +``` + +### Options inherited from parent commands + +``` + -y, --assume-yes If set, skips all confirmation prompts + --async If set, runs the command asynchronously + -o, --output-format string Output format, one of ["json" "pretty" "none" "yaml"] + -p, --project-id string Project ID + --region string Target region for region-specific requests + --verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info") +``` + +### SEE ALSO + +* [stackit beta kms key](./stackit_beta_kms_key.md) - Manage KMS Keys + diff --git a/docs/stackit_beta_kms_key_delete.md b/docs/stackit_beta_kms_key_delete.md new file mode 100644 index 000000000..26d7e1eb7 --- /dev/null +++ b/docs/stackit_beta_kms_key_delete.md @@ -0,0 +1,42 @@ +## stackit beta kms key delete + +Deletes a KMS Key + +### Synopsis + +Deletes a KMS Key inside a specific Key Ring. + +``` +stackit beta kms key delete [flags] +``` + +### Examples + +``` + Delete a KMS Key "my-key-id" inside the Key Ring "my-key-ring-id" + $ stackit beta kms keyring delete --key-ring "my-key-ring-id" --key "my-key-id" +``` + +### Options + +``` + -h, --help Help for "stackit beta kms key delete" + --key string ID of the actual Key + --key-ring string ID of the KMS Key Ring where the Key is stored +``` + +### Options inherited from parent commands + +``` + -y, --assume-yes If set, skips all confirmation prompts + --async If set, runs the command asynchronously + -o, --output-format string Output format, one of ["json" "pretty" "none" "yaml"] + -p, --project-id string Project ID + --region string Target region for region-specific requests + --verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info") +``` + +### SEE ALSO + +* [stackit beta kms key](./stackit_beta_kms_key.md) - Manage KMS Keys + diff --git a/docs/stackit_beta_kms_key_import.md b/docs/stackit_beta_kms_key_import.md new file mode 100644 index 000000000..c7addbab4 --- /dev/null +++ b/docs/stackit_beta_kms_key_import.md @@ -0,0 +1,44 @@ +## stackit beta kms key import + +Import a KMS Key Version + +### Synopsis + +Improt a new version to the given KMS key. + +``` +stackit beta kms key import [flags] +``` + +### Examples + +``` + Import a new version for the given KMS Key "my-key" + $ stakit beta kms key improt --key-ring "my-keyring-id" --key "my-key-id" --wrapped-key "base64-encoded-wrapped-key-material" --wrapping-key-id "my-wrapping-key-id" +``` + +### Options + +``` + -h, --help Help for "stackit beta kms key import" + --key string ID of the KMS Key + --key-ring string ID of the KMS Key Ring + --wrapped-key string The wrapped key material that has to be imported. Encoded in base64 + --wrapping-key-id string he unique id of the wrapping key the key material has been wrapped with +``` + +### Options inherited from parent commands + +``` + -y, --assume-yes If set, skips all confirmation prompts + --async If set, runs the command asynchronously + -o, --output-format string Output format, one of ["json" "pretty" "none" "yaml"] + -p, --project-id string Project ID + --region string Target region for region-specific requests + --verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info") +``` + +### SEE ALSO + +* [stackit beta kms key](./stackit_beta_kms_key.md) - Manage KMS Keys + diff --git a/docs/stackit_beta_kms_key_list.md b/docs/stackit_beta_kms_key_list.md new file mode 100644 index 000000000..886f1dbfe --- /dev/null +++ b/docs/stackit_beta_kms_key_list.md @@ -0,0 +1,43 @@ +## stackit beta kms key list + +Lists all KMS Keys + +### Synopsis + +Lists all KMS Keys inside a key ring. + +``` +stackit beta kms key list KEYRING_ID [flags] +``` + +### Examples + +``` + List all KMS Keys for the key ring "xxx" + $ stackit beta kms key list xxx + + List all KMS Keys in JSON format + $ stackit beta kms key list xxx --output-format json +``` + +### Options + +``` + -h, --help Help for "stackit beta kms key list" +``` + +### Options inherited from parent commands + +``` + -y, --assume-yes If set, skips all confirmation prompts + --async If set, runs the command asynchronously + -o, --output-format string Output format, one of ["json" "pretty" "none" "yaml"] + -p, --project-id string Project ID + --region string Target region for region-specific requests + --verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info") +``` + +### SEE ALSO + +* [stackit beta kms key](./stackit_beta_kms_key.md) - Manage KMS Keys + diff --git a/docs/stackit_beta_kms_key_restore.md b/docs/stackit_beta_kms_key_restore.md new file mode 100644 index 000000000..ca40478fe --- /dev/null +++ b/docs/stackit_beta_kms_key_restore.md @@ -0,0 +1,42 @@ +## stackit beta kms key restore + +Resotre a Key + +### Synopsis + +Restores the given key from being deleted. + +``` +stackit beta kms key restore [flags] +``` + +### Examples + +``` + Restore a KMS Key "my-key-id" inside the Key Ring "my-key-ring-id" that was scheduled for deletion. + $ stackit beta kms keyring restore --key-ring "my-key-ring-id" --key "my-key-id" +``` + +### Options + +``` + -h, --help Help for "stackit beta kms key restore" + --key string ID of the actual Key + --key-ring string ID of the KMS Key Ring where the Key is stored +``` + +### Options inherited from parent commands + +``` + -y, --assume-yes If set, skips all confirmation prompts + --async If set, runs the command asynchronously + -o, --output-format string Output format, one of ["json" "pretty" "none" "yaml"] + -p, --project-id string Project ID + --region string Target region for region-specific requests + --verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info") +``` + +### SEE ALSO + +* [stackit beta kms key](./stackit_beta_kms_key.md) - Manage KMS Keys + diff --git a/docs/stackit_beta_kms_key_rotate.md b/docs/stackit_beta_kms_key_rotate.md new file mode 100644 index 000000000..0beb5eefc --- /dev/null +++ b/docs/stackit_beta_kms_key_rotate.md @@ -0,0 +1,42 @@ +## stackit beta kms key rotate + +Rotate a key + +### Synopsis + +Rotates the given key. + +``` +stackit beta kms key rotate [flags] +``` + +### Examples + +``` + Rotate a KMS Key "my-key-id" and increase it's version inside the Key Ring "my-key-ring-id". + $ stackit beta kms keyring rotate --key-ring "my-key-ring-id" --key "my-key-id" +``` + +### Options + +``` + -h, --help Help for "stackit beta kms key rotate" + --key string ID of the actual Key + --key-ring string ID of the KMS Key Ring where the Key is stored +``` + +### Options inherited from parent commands + +``` + -y, --assume-yes If set, skips all confirmation prompts + --async If set, runs the command asynchronously + -o, --output-format string Output format, one of ["json" "pretty" "none" "yaml"] + -p, --project-id string Project ID + --region string Target region for region-specific requests + --verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info") +``` + +### SEE ALSO + +* [stackit beta kms key](./stackit_beta_kms_key.md) - Manage KMS Keys + diff --git a/docs/stackit_beta_kms_keyring.md b/docs/stackit_beta_kms_keyring.md new file mode 100644 index 000000000..75c548b99 --- /dev/null +++ b/docs/stackit_beta_kms_keyring.md @@ -0,0 +1,36 @@ +## stackit beta kms keyring + +Manage KMS Keyrings + +### Synopsis + +Provides functionality for Keyring operations inside the KMS + +``` +stackit beta kms keyring [flags] +``` + +### Options + +``` + -h, --help Help for "stackit beta kms keyring" +``` + +### Options inherited from parent commands + +``` + -y, --assume-yes If set, skips all confirmation prompts + --async If set, runs the command asynchronously + -o, --output-format string Output format, one of ["json" "pretty" "none" "yaml"] + -p, --project-id string Project ID + --region string Target region for region-specific requests + --verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info") +``` + +### SEE ALSO + +* [stackit beta kms](./stackit_beta_kms.md) - Provides functionality for KMS +* [stackit beta kms keyring create](./stackit_beta_kms_keyring_create.md) - Creates a KMS Key Ring +* [stackit beta kms keyring delete](./stackit_beta_kms_keyring_delete.md) - Deletes a KMS Keyring +* [stackit beta kms keyring list](./stackit_beta_kms_keyring_list.md) - Lists all KMS Keyrings + diff --git a/docs/stackit_beta_kms_keyring_create.md b/docs/stackit_beta_kms_keyring_create.md new file mode 100644 index 000000000..7cda1df7d --- /dev/null +++ b/docs/stackit_beta_kms_keyring_create.md @@ -0,0 +1,45 @@ +## stackit beta kms keyring create + +Creates a KMS Key Ring + +### Synopsis + +Creates a KMS Key Ring. + +``` +stackit beta kms keyring create [flags] +``` + +### Examples + +``` + Create a KMS key ring + $ stakit beta kms keyring create --name my-keyring + + Create a KMS Key ring with a description + $ stakit beta kms keyring create --name my-keyring --description my-description +``` + +### Options + +``` + --description string Optinal description of the Key Ring + -h, --help Help for "stackit beta kms keyring create" + --name string Name of the KMS Key Ring +``` + +### Options inherited from parent commands + +``` + -y, --assume-yes If set, skips all confirmation prompts + --async If set, runs the command asynchronously + -o, --output-format string Output format, one of ["json" "pretty" "none" "yaml"] + -p, --project-id string Project ID + --region string Target region for region-specific requests + --verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info") +``` + +### SEE ALSO + +* [stackit beta kms keyring](./stackit_beta_kms_keyring.md) - Manage KMS Keyrings + diff --git a/docs/stackit_beta_kms_keyring_delete.md b/docs/stackit_beta_kms_keyring_delete.md new file mode 100644 index 000000000..ec5eff147 --- /dev/null +++ b/docs/stackit_beta_kms_keyring_delete.md @@ -0,0 +1,40 @@ +## stackit beta kms keyring delete + +Deletes a KMS Keyring + +### Synopsis + +Deletes a KMS Keyring. + +``` +stackit beta kms keyring delete KEYRING_ID [flags] +``` + +### Examples + +``` + Delete a KMS Keyring with ID "xxx" + $ stackit beta kms keyring delete xxx +``` + +### Options + +``` + -h, --help Help for "stackit beta kms keyring delete" +``` + +### Options inherited from parent commands + +``` + -y, --assume-yes If set, skips all confirmation prompts + --async If set, runs the command asynchronously + -o, --output-format string Output format, one of ["json" "pretty" "none" "yaml"] + -p, --project-id string Project ID + --region string Target region for region-specific requests + --verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info") +``` + +### SEE ALSO + +* [stackit beta kms keyring](./stackit_beta_kms_keyring.md) - Manage KMS Keyrings + diff --git a/docs/stackit_beta_kms_keyring_list.md b/docs/stackit_beta_kms_keyring_list.md new file mode 100644 index 000000000..ab71de5d3 --- /dev/null +++ b/docs/stackit_beta_kms_keyring_list.md @@ -0,0 +1,43 @@ +## stackit beta kms keyring list + +Lists all KMS Keyrings + +### Synopsis + +Lists all KMS Keyrings. + +``` +stackit beta kms keyring list [flags] +``` + +### Examples + +``` + List all KMS Keyrings + $ stackit beta kms keyring list + + List all KMS Keyrings in JSON format + $ stackit beta kms keyring list --output-format json +``` + +### Options + +``` + -h, --help Help for "stackit beta kms keyring list" +``` + +### Options inherited from parent commands + +``` + -y, --assume-yes If set, skips all confirmation prompts + --async If set, runs the command asynchronously + -o, --output-format string Output format, one of ["json" "pretty" "none" "yaml"] + -p, --project-id string Project ID + --region string Target region for region-specific requests + --verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info") +``` + +### SEE ALSO + +* [stackit beta kms keyring](./stackit_beta_kms_keyring.md) - Manage KMS Keyrings + diff --git a/docs/stackit_beta_kms_version.md b/docs/stackit_beta_kms_version.md new file mode 100644 index 000000000..e0de4020d --- /dev/null +++ b/docs/stackit_beta_kms_version.md @@ -0,0 +1,38 @@ +## stackit beta kms version + +Manage KMS Key versions + +### Synopsis + +Provides CRUD functionality for Key Version operations inside the KMS + +``` +stackit beta kms version [flags] +``` + +### Options + +``` + -h, --help Help for "stackit beta kms version" +``` + +### Options inherited from parent commands + +``` + -y, --assume-yes If set, skips all confirmation prompts + --async If set, runs the command asynchronously + -o, --output-format string Output format, one of ["json" "pretty" "none" "yaml"] + -p, --project-id string Project ID + --region string Target region for region-specific requests + --verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info") +``` + +### SEE ALSO + +* [stackit beta kms](./stackit_beta_kms.md) - Provides functionality for KMS +* [stackit beta kms version destroy](./stackit_beta_kms_version_destroy.md) - Destroy a Key Versions +* [stackit beta kms version disable](./stackit_beta_kms_version_disable.md) - Disable a Key Versions +* [stackit beta kms version enable](./stackit_beta_kms_version_enable.md) - Enable a Key Versions +* [stackit beta kms version list](./stackit_beta_kms_version_list.md) - Lists all Key Versions +* [stackit beta kms version restore](./stackit_beta_kms_version_restore.md) - Restore a Key Versions + diff --git a/docs/stackit_beta_kms_version_destroy.md b/docs/stackit_beta_kms_version_destroy.md new file mode 100644 index 000000000..fe9e2a466 --- /dev/null +++ b/docs/stackit_beta_kms_version_destroy.md @@ -0,0 +1,43 @@ +## stackit beta kms version destroy + +Destroy a Key Versions + +### Synopsis + +Removes the key material of a version. + +``` +stackit beta kms version destroy [flags] +``` + +### Examples + +``` + Destroy key version "0" for the key "my-key-id" inside the key ring "my-key-ring-id" + $ stackit beta kms version destroy --key "my-key-id" --key-ring "my-key-ring-id" --version 0 +``` + +### Options + +``` + -h, --help Help for "stackit beta kms version destroy" + --key string ID of the Key + --key-ring string ID of the KMS Key Ring + --version int Version number of the key +``` + +### Options inherited from parent commands + +``` + -y, --assume-yes If set, skips all confirmation prompts + --async If set, runs the command asynchronously + -o, --output-format string Output format, one of ["json" "pretty" "none" "yaml"] + -p, --project-id string Project ID + --region string Target region for region-specific requests + --verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info") +``` + +### SEE ALSO + +* [stackit beta kms version](./stackit_beta_kms_version.md) - Manage KMS Key versions + diff --git a/docs/stackit_beta_kms_version_disable.md b/docs/stackit_beta_kms_version_disable.md new file mode 100644 index 000000000..a8f1f6c1a --- /dev/null +++ b/docs/stackit_beta_kms_version_disable.md @@ -0,0 +1,43 @@ +## stackit beta kms version disable + +Disable a Key Versions + +### Synopsis + +Disable the given key version. + +``` +stackit beta kms version disable [flags] +``` + +### Examples + +``` + Disable key version "0" for the key "my-key-id" inside the key ring "my-key-ring-id" + $ stackit beta kms version disable --key "my-key-id" --key-ring "my-key-ring-id" --version 0 +``` + +### Options + +``` + -h, --help Help for "stackit beta kms version disable" + --key string ID of the Key + --key-ring string ID of the KMS Key Ring + --version int Version number of the key +``` + +### Options inherited from parent commands + +``` + -y, --assume-yes If set, skips all confirmation prompts + --async If set, runs the command asynchronously + -o, --output-format string Output format, one of ["json" "pretty" "none" "yaml"] + -p, --project-id string Project ID + --region string Target region for region-specific requests + --verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info") +``` + +### SEE ALSO + +* [stackit beta kms version](./stackit_beta_kms_version.md) - Manage KMS Key versions + diff --git a/docs/stackit_beta_kms_version_enable.md b/docs/stackit_beta_kms_version_enable.md new file mode 100644 index 000000000..0839b39cf --- /dev/null +++ b/docs/stackit_beta_kms_version_enable.md @@ -0,0 +1,43 @@ +## stackit beta kms version enable + +Enable a Key Versions + +### Synopsis + +Enable the given key version. + +``` +stackit beta kms version enable [flags] +``` + +### Examples + +``` + Enable key version "0" for the key "my-key-id" inside the key ring "my-key-ring-id" + $ stackit beta kms version enable --key "my-key-id" --key-ring "my-key-ring-id" --version 0 +``` + +### Options + +``` + -h, --help Help for "stackit beta kms version enable" + --key string ID of the Key + --key-ring string ID of the KMS Key Ring + --version int Version number of the key +``` + +### Options inherited from parent commands + +``` + -y, --assume-yes If set, skips all confirmation prompts + --async If set, runs the command asynchronously + -o, --output-format string Output format, one of ["json" "pretty" "none" "yaml"] + -p, --project-id string Project ID + --region string Target region for region-specific requests + --verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info") +``` + +### SEE ALSO + +* [stackit beta kms version](./stackit_beta_kms_version.md) - Manage KMS Key versions + diff --git a/docs/stackit_beta_kms_version_list.md b/docs/stackit_beta_kms_version_list.md new file mode 100644 index 000000000..fef9bd88b --- /dev/null +++ b/docs/stackit_beta_kms_version_list.md @@ -0,0 +1,45 @@ +## stackit beta kms version list + +Lists all Key Versions + +### Synopsis + +Lists all versions of a given key. + +``` +stackit beta kms version list [flags] +``` + +### Examples + +``` + List all key versions for the key "my-key-id" inside the key ring "my-key-ring-id" + $ stackit beta kms version list --key "my-key-id" --key-ring "my-key-ring-id" + + List all key versions in JSON format + $ stackit beta kms version list --key "my-key-id" --key-ring "my-key-ring-id" -o json +``` + +### Options + +``` + -h, --help Help for "stackit beta kms version list" + --key string ID of the Key + --key-ring string ID of the KMS Key Ring +``` + +### Options inherited from parent commands + +``` + -y, --assume-yes If set, skips all confirmation prompts + --async If set, runs the command asynchronously + -o, --output-format string Output format, one of ["json" "pretty" "none" "yaml"] + -p, --project-id string Project ID + --region string Target region for region-specific requests + --verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info") +``` + +### SEE ALSO + +* [stackit beta kms version](./stackit_beta_kms_version.md) - Manage KMS Key versions + diff --git a/docs/stackit_beta_kms_version_restore.md b/docs/stackit_beta_kms_version_restore.md new file mode 100644 index 000000000..25b061d63 --- /dev/null +++ b/docs/stackit_beta_kms_version_restore.md @@ -0,0 +1,43 @@ +## stackit beta kms version restore + +Restore a Key Versions + +### Synopsis + +Restores the specified version of key. + +``` +stackit beta kms version restore [flags] +``` + +### Examples + +``` + Restore key version "0" for the key "my-key-id" inside the key ring "my-key-ring-id" + $ stackit beta kms version restore --key "my-key-id" --key-ring "my-key-ring-id" --version 0 +``` + +### Options + +``` + -h, --help Help for "stackit beta kms version restore" + --key string ID of the Key + --key-ring string ID of the KMS Key Ring + --version int Version number of the key +``` + +### Options inherited from parent commands + +``` + -y, --assume-yes If set, skips all confirmation prompts + --async If set, runs the command asynchronously + -o, --output-format string Output format, one of ["json" "pretty" "none" "yaml"] + -p, --project-id string Project ID + --region string Target region for region-specific requests + --verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info") +``` + +### SEE ALSO + +* [stackit beta kms version](./stackit_beta_kms_version.md) - Manage KMS Key versions + diff --git a/docs/stackit_beta_kms_wrappingkey.md b/docs/stackit_beta_kms_wrappingkey.md new file mode 100644 index 000000000..4d5548c01 --- /dev/null +++ b/docs/stackit_beta_kms_wrappingkey.md @@ -0,0 +1,36 @@ +## stackit beta kms wrappingkey + +Manage KMS Wrapping Keys + +### Synopsis + +Provides CRUD functionality for Wrapping Key operations inside the KMS + +``` +stackit beta kms wrappingkey [flags] +``` + +### Options + +``` + -h, --help Help for "stackit beta kms wrappingkey" +``` + +### Options inherited from parent commands + +``` + -y, --assume-yes If set, skips all confirmation prompts + --async If set, runs the command asynchronously + -o, --output-format string Output format, one of ["json" "pretty" "none" "yaml"] + -p, --project-id string Project ID + --region string Target region for region-specific requests + --verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info") +``` + +### SEE ALSO + +* [stackit beta kms](./stackit_beta_kms.md) - Provides functionality for KMS +* [stackit beta kms wrappingkey create](./stackit_beta_kms_wrappingkey_create.md) - Creates a KMS Wrapping Key +* [stackit beta kms wrappingkey delete](./stackit_beta_kms_wrappingkey_delete.md) - Deletes a KMS Wrapping Key +* [stackit beta kms wrappingkey list](./stackit_beta_kms_wrappingkey_list.md) - Lists all KMS Wrapping Keys + diff --git a/docs/stackit_beta_kms_wrappingkey_create.md b/docs/stackit_beta_kms_wrappingkey_create.md new file mode 100644 index 000000000..ab44e5e63 --- /dev/null +++ b/docs/stackit_beta_kms_wrappingkey_create.md @@ -0,0 +1,49 @@ +## stackit beta kms wrappingkey create + +Creates a KMS Wrapping Key + +### Synopsis + +Creates a KMS Wrapping Key. + +``` +stackit beta kms wrappingkey create [flags] +``` + +### Examples + +``` + Create a Symmetric KMS Wrapping Key + $ stakit beta kms wrappingkey create --key-ring "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-wrapping-key-name" --purpose "wrap_symmetric_key" + + Create an Asymmetric KMS Wrapping Key with a description + $ stakit beta kms wrappingkey create --key-ring "my-keyring-id" --algorithm "hmac_sha256" --name "my-wrapping-key-name" --description "my-description" --purpose "wrap_asymmetric_key" +``` + +### Options + +``` + --algorithm string En-/Decryption algorithm + --backend string The backend that is responsible for maintaining this wrapping key (default "software") + --description string Optinal description of the Wrapping Key + -h, --help Help for "stackit beta kms wrappingkey create" + --key-ring string ID of the KMS Key Ring + --name string The display name to distinguish multiple wrapping keys + --purpose string Purpose of the Wrapping Key. Enum: 'wrap_symmetric_key', 'wrap_asymmetric_key' +``` + +### Options inherited from parent commands + +``` + -y, --assume-yes If set, skips all confirmation prompts + --async If set, runs the command asynchronously + -o, --output-format string Output format, one of ["json" "pretty" "none" "yaml"] + -p, --project-id string Project ID + --region string Target region for region-specific requests + --verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info") +``` + +### SEE ALSO + +* [stackit beta kms wrappingkey](./stackit_beta_kms_wrappingkey.md) - Manage KMS Wrapping Keys + diff --git a/docs/stackit_beta_kms_wrappingkey_delete.md b/docs/stackit_beta_kms_wrappingkey_delete.md new file mode 100644 index 000000000..e1813b7d8 --- /dev/null +++ b/docs/stackit_beta_kms_wrappingkey_delete.md @@ -0,0 +1,42 @@ +## stackit beta kms wrappingkey delete + +Deletes a KMS Wrapping Key + +### Synopsis + +Deletes a KMS Wrapping Key inside a specific Key Ring. + +``` +stackit beta kms wrappingkey delete [flags] +``` + +### Examples + +``` + Delete a KMS Wrapping Key "my-wrapping-key-id" inside the Key Ring "my-key-ring-id" + $ stackit beta kms keyring delete --key-ring "my-key-ring-id" --wrapping-key "my-wrapping-key-id" +``` + +### Options + +``` + -h, --help Help for "stackit beta kms wrappingkey delete" + --key-ring string ID of the KMS Key Ring where the Wrapping Key is stored + --wrapping-key string ID of the actual Wrapping Key +``` + +### Options inherited from parent commands + +``` + -y, --assume-yes If set, skips all confirmation prompts + --async If set, runs the command asynchronously + -o, --output-format string Output format, one of ["json" "pretty" "none" "yaml"] + -p, --project-id string Project ID + --region string Target region for region-specific requests + --verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info") +``` + +### SEE ALSO + +* [stackit beta kms wrappingkey](./stackit_beta_kms_wrappingkey.md) - Manage KMS Wrapping Keys + diff --git a/docs/stackit_beta_kms_wrappingkey_list.md b/docs/stackit_beta_kms_wrappingkey_list.md new file mode 100644 index 000000000..8cf83d10d --- /dev/null +++ b/docs/stackit_beta_kms_wrappingkey_list.md @@ -0,0 +1,43 @@ +## stackit beta kms wrappingkey list + +Lists all KMS Wrapping Keys + +### Synopsis + +Lists all KMS Wrapping Keys inside a key ring. + +``` +stackit beta kms wrappingkey list KEYRING_ID [flags] +``` + +### Examples + +``` + List all KMS Wrapping Keys for the key ring "xxx" + $ stackit beta kms wrappingkeys list xxx + + List all KMS Wrapping Keys in JSON format + $ stackit beta kms wrappingkeys list xxx --output-format json +``` + +### Options + +``` + -h, --help Help for "stackit beta kms wrappingkey list" +``` + +### Options inherited from parent commands + +``` + -y, --assume-yes If set, skips all confirmation prompts + --async If set, runs the command asynchronously + -o, --output-format string Output format, one of ["json" "pretty" "none" "yaml"] + -p, --project-id string Project ID + --region string Target region for region-specific requests + --verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info") +``` + +### SEE ALSO + +* [stackit beta kms wrappingkey](./stackit_beta_kms_wrappingkey.md) - Manage KMS Wrapping Keys + diff --git a/docs/stackit_config_set.md b/docs/stackit_config_set.md index b1abf5662..9b07e46b5 100644 --- a/docs/stackit_config_set.md +++ b/docs/stackit_config_set.md @@ -36,6 +36,7 @@ stackit config set [flags] --iaas-custom-endpoint string IaaS API base URL, used in calls to this API --identity-provider-custom-client-id string Identity Provider client ID, used for user authentication --identity-provider-custom-well-known-configuration string Identity Provider well-known OpenID configuration URL, used for user authentication + --kms-custom-endpoint string KMS API base URL, used in calls to this API --load-balancer-custom-endpoint string Load Balancer API base URL, used in calls to this API --logme-custom-endpoint string LogMe API base URL, used in calls to this API --mariadb-custom-endpoint string MariaDB API base URL, used in calls to this API diff --git a/docs/stackit_config_unset.md b/docs/stackit_config_unset.md index 4a48b759e..9d4c83088 100644 --- a/docs/stackit_config_unset.md +++ b/docs/stackit_config_unset.md @@ -34,6 +34,7 @@ stackit config unset [flags] --iaas-custom-endpoint IaaS API base URL. If unset, uses the default base URL --identity-provider-custom-client-id Identity Provider client ID, used for user authentication --identity-provider-custom-well-known-configuration Identity Provider well-known OpenID configuration URL. If unset, uses the default identity provider + --kms-custom-endpoint KMS API base URL. If unset, uses the default base URL --load-balancer-custom-endpoint Load Balancer API base URL. If unset, uses the default base URL --logme-custom-endpoint LogMe API base URL. If unset, uses the default base URL --mariadb-custom-endpoint MariaDB API base URL. If unset, uses the default base URL From ab298b581a156154a2a713fd35a6806ad4ad90e5 Mon Sep 17 00:00:00 2001 From: Jan Sternagel Date: Sat, 23 Aug 2025 23:57:46 +0200 Subject: [PATCH 07/52] added kms to go.mod and go.sum --- go.mod | 1 + go.sum | 2 ++ 2 files changed, 3 insertions(+) diff --git a/go.mod b/go.mod index 125b89639..72b689349 100644 --- a/go.mod +++ b/go.mod @@ -238,6 +238,7 @@ require ( github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.14.0 // indirect github.com/spf13/cast v1.7.1 // indirect + github.com/stackitcloud/stackit-sdk-go/services/kms v0.5.1 github.com/stackitcloud/stackit-sdk-go/services/loadbalancer v1.5.1 github.com/stackitcloud/stackit-sdk-go/services/logme v0.25.1 github.com/stackitcloud/stackit-sdk-go/services/mariadb v0.25.1 diff --git a/go.sum b/go.sum index 25bb26a89..79272c1f8 100644 --- a/go.sum +++ b/go.sum @@ -575,6 +575,8 @@ github.com/stackitcloud/stackit-sdk-go/services/git v0.7.1 h1:hkFixFnBcQzU4BSIZF github.com/stackitcloud/stackit-sdk-go/services/git v0.7.1/go.mod h1:Ng1EzrRndG3iGXGH90AZJz//wfK+2YOyDwTnTLwX3a4= github.com/stackitcloud/stackit-sdk-go/services/iaas v0.29.1 h1:GfE+FaeIKSVaKvgzh8Eacum+bQVyRS6ngltkh0qNGtM= github.com/stackitcloud/stackit-sdk-go/services/iaas v0.29.1/go.mod h1:b/jgJf7QHdRzU2fmZeJJtu5j0TAevDRghzcn5MyRmOI= +github.com/stackitcloud/stackit-sdk-go/services/kms v0.5.1 h1:QWG78oHtX5tjTQSnLpsBSgrYPEf2nDnb8nhE+K3NztA= +github.com/stackitcloud/stackit-sdk-go/services/kms v0.5.1/go.mod h1:KEPVoO21pC4bjy5l0nyhjUJ0+uVwVWb+k2TYrzJ8xYw= github.com/stackitcloud/stackit-sdk-go/services/loadbalancer v1.5.1 h1:OdJEs8eOfrzn9tCBDLxIyP8hX50zPfcXNYnRoQX+chs= github.com/stackitcloud/stackit-sdk-go/services/loadbalancer v1.5.1/go.mod h1:11uzaOPCF9SeDHXEGOPMlHDD3J5r2TnvCGUwW9Igq9c= github.com/stackitcloud/stackit-sdk-go/services/logme v0.25.1 h1:hv5WrRU9rN6Jx4OwdOGJRyaQrfA9p1tzEoQK6/CDyoA= From 3ea181c26ad4ffccf2fc5eecb6944fa2e5035db1 Mon Sep 17 00:00:00 2001 From: Jan Sternagel Date: Fri, 5 Sep 2025 21:14:37 +0200 Subject: [PATCH 08/52] fix spelling --- docs/stackit_beta_kms_key_import.md | 7 +++---- internal/cmd/beta/kms/key/importKey/importKey.go | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/docs/stackit_beta_kms_key_import.md b/docs/stackit_beta_kms_key_import.md index c7addbab4..07a32a019 100644 --- a/docs/stackit_beta_kms_key_import.md +++ b/docs/stackit_beta_kms_key_import.md @@ -4,7 +4,7 @@ Import a KMS Key Version ### Synopsis -Improt a new version to the given KMS key. +Import a new version to the given KMS key. ``` stackit beta kms key import [flags] @@ -14,7 +14,7 @@ stackit beta kms key import [flags] ``` Import a new version for the given KMS Key "my-key" - $ stakit beta kms key improt --key-ring "my-keyring-id" --key "my-key-id" --wrapped-key "base64-encoded-wrapped-key-material" --wrapping-key-id "my-wrapping-key-id" + $ stakit beta kms key import --key-ring "my-keyring-id" --key "my-key-id" --wrapped-key "base64-encoded-wrapped-key-material" --wrapping-key-id "my-wrapping-key-id" ``` ### Options @@ -40,5 +40,4 @@ stackit beta kms key import [flags] ### SEE ALSO -* [stackit beta kms key](./stackit_beta_kms_key.md) - Manage KMS Keys - +- [stackit beta kms key](./stackit_beta_kms_key.md) - Manage KMS Keys diff --git a/internal/cmd/beta/kms/key/importKey/importKey.go b/internal/cmd/beta/kms/key/importKey/importKey.go index 935c1ef9d..35bc870c0 100644 --- a/internal/cmd/beta/kms/key/importKey/importKey.go +++ b/internal/cmd/beta/kms/key/importKey/importKey.go @@ -42,12 +42,12 @@ func NewCmd(params *params.CmdParams) *cobra.Command { cmd := &cobra.Command{ Use: "import", Short: "Import a KMS Key Version", - Long: "Improt a new version to the given KMS key.", + Long: "Import a new version to the given KMS key.", Args: args.NoArgs, Example: examples.Build( examples.NewExample( `Import a new version for the given KMS Key "my-key"`, - `$ stakit beta kms key improt --key-ring "my-keyring-id" --key "my-key-id" --wrapped-key "base64-encoded-wrapped-key-material" --wrapping-key-id "my-wrapping-key-id"`), + `$ stakit beta kms key import --key-ring "my-keyring-id" --key "my-key-id" --wrapped-key "base64-encoded-wrapped-key-material" --wrapping-key-id "my-wrapping-key-id"`), ), RunE: func(cmd *cobra.Command, _ []string) error { ctx := context.Background() From ada9a5414d443994c5297f1998d89879107348f5 Mon Sep 17 00:00:00 2001 From: Jan Sternagel Date: Fri, 5 Sep 2025 22:30:23 +0200 Subject: [PATCH 09/52] yaml/json format added --- internal/cmd/beta/kms/key/delete/delete.go | 52 ++++++++++++++++++- .../cmd/beta/kms/key/delete/delete_test.go | 48 +++++++++++++++++ .../cmd/beta/kms/version/restore/restore.go | 2 +- 3 files changed, 99 insertions(+), 3 deletions(-) diff --git a/internal/cmd/beta/kms/key/delete/delete.go b/internal/cmd/beta/kms/key/delete/delete.go index ddb60c137..8bd1f2a09 100644 --- a/internal/cmd/beta/kms/key/delete/delete.go +++ b/internal/cmd/beta/kms/key/delete/delete.go @@ -2,8 +2,11 @@ package delete import ( "context" + "encoding/json" "fmt" + "time" + "github.com/goccy/go-yaml" "github.com/spf13/cobra" "github.com/stackitcloud/stackit-cli/internal/cmd/params" "github.com/stackitcloud/stackit-cli/internal/pkg/args" @@ -82,8 +85,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { return err } - params.Printer.Info("Deletion of KMS Key %q scheduled successfully for the deletion date: %q\n", keyName, deletionDate) - return nil + return outputResult(params.Printer, model.OutputFormat, model.KeyId, keyName, deletionDate) }, } @@ -138,3 +140,49 @@ func configureFlags(cmd *cobra.Command) { err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, keyIdFlag) cobra.CheckErr(err) } + +func outputResult(p *print.Printer, outputFormat, keyId, keyName string, deletionDate time.Time) error { + switch outputFormat { + case print.JSONOutputFormat: + details := struct { + KeyId string `json:"keyId"` + KeyName string `json:"keyName"` + Status string `json:"status"` + DeletionDate time.Time `json:"deletionDate"` + }{ + KeyId: keyId, + KeyName: keyName, + Status: "Deletion Scheduled", + DeletionDate: deletionDate, + } + b, err := json.MarshalIndent(details, "", " ") + if err != nil { + return fmt.Errorf("marshal output to JSON: %w", err) + } + p.Outputln(string(b)) + return nil + + case print.YAMLOutputFormat: + details := struct { + KeyId string `yaml:"keyId"` + KeyName string `yaml:"keyName"` + Status string `yaml:"status"` + DeletionDate time.Time `yaml:"deletionDate"` + }{ + KeyId: keyId, + KeyName: keyName, + Status: "Deletion Scheduled", + DeletionDate: deletionDate, + } + b, err := yaml.Marshal(details) + if err != nil { + return fmt.Errorf("marshal output to YAML: %w", err) + } + p.Outputln(string(b)) + return nil + + default: + p.Outputf("Deletion of KMS Key %q scheduled successfully for the deletion date: %q\n", keyName, deletionDate) + return nil + } +} diff --git a/internal/cmd/beta/kms/key/delete/delete_test.go b/internal/cmd/beta/kms/key/delete/delete_test.go index 61e02c45e..8a35ebcfa 100644 --- a/internal/cmd/beta/kms/key/delete/delete_test.go +++ b/internal/cmd/beta/kms/key/delete/delete_test.go @@ -3,11 +3,13 @@ package delete import ( "context" "testing" + "time" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/uuid" "github.com/spf13/cobra" + "github.com/stackitcloud/stackit-cli/internal/cmd/params" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/print" "github.com/stackitcloud/stackit-sdk-go/services/kms" @@ -225,3 +227,49 @@ func TestBuildRequest(t *testing.T) { }) } } + +func TestOutputResult(t *testing.T) { + tests := []struct { + description string + wantErr bool + outputFormat string + keyId string + keyName string + deltionDate time.Time + }{ + { + description: "default output", + keyId: uuid.NewString(), + keyName: uuid.NewString(), + deltionDate: time.Now(), + wantErr: false, + }, + { + description: "json output", + outputFormat: print.JSONOutputFormat, + keyId: uuid.NewString(), + keyName: uuid.NewString(), + deltionDate: time.Now(), + wantErr: false, + }, + { + description: "yaml output", + outputFormat: print.YAMLOutputFormat, + keyId: uuid.NewString(), + keyName: uuid.NewString(), + deltionDate: time.Now(), + wantErr: false, + }, + } + + p := print.NewPrinter() + p.Cmd = NewCmd(¶ms.CmdParams{Printer: p}) + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + err := outputResult(p, tt.outputFormat, tt.keyId, tt.keyName, tt.deltionDate) + if (err != nil) != tt.wantErr { + t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/internal/cmd/beta/kms/version/restore/restore.go b/internal/cmd/beta/kms/version/restore/restore.go index c059391b9..c595879d0 100644 --- a/internal/cmd/beta/kms/version/restore/restore.go +++ b/internal/cmd/beta/kms/version/restore/restore.go @@ -69,7 +69,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { return fmt.Errorf("restore Key Version: %w", err) } - params.Printer.Info("Restored version %d of Key %q\n", *model.VersionNumber, keyName) + params.Printer.Outputf("Restored version %d of Key %q\n", *model.VersionNumber, keyName) return nil }, } From 7bbcd7a341a00985fa64d0322b0f81608e7c253c Mon Sep 17 00:00:00 2001 From: Jan Sternagel Date: Fri, 5 Sep 2025 22:32:15 +0200 Subject: [PATCH 10/52] empty responses also handeld in json/yaml format --- internal/cmd/beta/kms/key/list/list.go | 13 ++++++------- internal/cmd/beta/kms/key/list/list_test.go | 10 +++++++++- internal/cmd/beta/kms/keyring/list/list.go | 15 +++++++-------- internal/cmd/beta/kms/keyring/list/list_test.go | 6 +++++- internal/cmd/beta/kms/version/list/list.go | 13 ++++++------- internal/cmd/beta/kms/version/list/list_test.go | 10 +++++++++- internal/cmd/beta/kms/wrappingkey/list/list.go | 13 ++++++------- .../cmd/beta/kms/wrappingkey/list/list_test.go | 4 +++- 8 files changed, 51 insertions(+), 33 deletions(-) diff --git a/internal/cmd/beta/kms/key/list/list.go b/internal/cmd/beta/kms/key/list/list.go index 191acccd5..adecbc958 100644 --- a/internal/cmd/beta/kms/key/list/list.go +++ b/internal/cmd/beta/kms/key/list/list.go @@ -61,13 +61,8 @@ func NewCmd(params *params.CmdParams) *cobra.Command { if err != nil { return fmt.Errorf("get KMS Keys: %w", err) } - if resp.Keys == nil || len(*resp.Keys) == 0 { - params.Printer.Info("No Keys found for project %q in region %q under the key ring %q\n", model.ProjectId, model.Region, model.KeyRingId) - return nil - } - keys := *resp.Keys - return outputResult(params.Printer, model.OutputFormat, keys) + return outputResult(params.Printer, model.OutputFormat, model.ProjectId, model.KeyRingId, *resp.Keys) }, } @@ -104,7 +99,7 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClie return req } -func outputResult(p *print.Printer, outputFormat string, keys []kms.Key) error { +func outputResult(p *print.Printer, outputFormat string, projectId, keyRingId string, keys []kms.Key) error { switch outputFormat { case print.JSONOutputFormat: details, err := json.MarshalIndent(keys, "", " ") @@ -123,6 +118,10 @@ func outputResult(p *print.Printer, outputFormat string, keys []kms.Key) error { return nil default: + if len(keys) == 0 { + p.Outputf("No Keys found for project %q under the key ring %q\n", projectId, keyRingId) + return nil + } table := tables.NewTable() table.SetHeader("ID", "NAME", "SCOPE", "ALGORITHM", "DELETION DATE", "STATUS") diff --git a/internal/cmd/beta/kms/key/list/list_test.go b/internal/cmd/beta/kms/key/list/list_test.go index 1ff9d44c3..65e4a11e9 100644 --- a/internal/cmd/beta/kms/key/list/list_test.go +++ b/internal/cmd/beta/kms/key/list/list_test.go @@ -215,6 +215,8 @@ func TestOutputResult(t *testing.T) { tests := []struct { description string keys []kms.Key + projectId string + keyRingId string outputFormat string wantErr bool }{ @@ -223,17 +225,23 @@ func TestOutputResult(t *testing.T) { { description: "default output", keys: []kms.Key{}, + projectId: uuid.NewString(), + keyRingId: uuid.NewString(), wantErr: false, }, { description: "json output", keys: []kms.Key{}, + projectId: uuid.NewString(), + keyRingId: uuid.NewString(), outputFormat: print.JSONOutputFormat, wantErr: false, }, { description: "yaml output", keys: []kms.Key{}, + projectId: uuid.NewString(), + keyRingId: uuid.NewString(), outputFormat: print.YAMLOutputFormat, wantErr: false, }, @@ -243,7 +251,7 @@ func TestOutputResult(t *testing.T) { p.Cmd = NewCmd(¶ms.CmdParams{Printer: p}) for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { - err := outputResult(p, tt.outputFormat, tt.keys) + err := outputResult(p, tt.outputFormat, tt.projectId, tt.keyRingId, tt.keys) if (err != nil) != tt.wantErr { t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr) } diff --git a/internal/cmd/beta/kms/keyring/list/list.go b/internal/cmd/beta/kms/keyring/list/list.go index e6cddeebf..a1fb00624 100644 --- a/internal/cmd/beta/kms/keyring/list/list.go +++ b/internal/cmd/beta/kms/keyring/list/list.go @@ -30,7 +30,6 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Long: "Lists all KMS Keyrings.", Args: args.NoArgs, Example: examples.Build( - // Enforce a specific region for the KMS examples.NewExample( `List all KMS Keyrings`, "$ stackit beta kms keyring list"), @@ -57,13 +56,8 @@ func NewCmd(params *params.CmdParams) *cobra.Command { if err != nil { return fmt.Errorf("get KMS Keyrings: %w", err) } - if resp.KeyRings == nil || len(*resp.KeyRings) == 0 { - params.Printer.Info("No Keyrings found for project %q in region %q\n", model.ProjectId, model.Region) - return nil - } - keyRings := *resp.KeyRings - return outputResult(params.Printer, model.OutputFormat, keyRings) + return outputResult(params.Printer, model.OutputFormat, model.ProjectId, *resp.KeyRings) }, } @@ -97,7 +91,7 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClie return req } -func outputResult(p *print.Printer, outputFormat string, keyRings []kms.KeyRing) error { +func outputResult(p *print.Printer, outputFormat, projectId string, keyRings []kms.KeyRing) error { switch outputFormat { case print.JSONOutputFormat: details, err := json.MarshalIndent(keyRings, "", " ") @@ -116,6 +110,11 @@ func outputResult(p *print.Printer, outputFormat string, keyRings []kms.KeyRing) return nil default: + if len(keyRings) == 0 { + p.Outputf("No Keyrings found for project %q\n", projectId) + return nil + } + table := tables.NewTable() table.SetHeader("ID", "NAME", "STATUS") diff --git a/internal/cmd/beta/kms/keyring/list/list_test.go b/internal/cmd/beta/kms/keyring/list/list_test.go index 30dad9d2c..ca8bdcfe9 100644 --- a/internal/cmd/beta/kms/keyring/list/list_test.go +++ b/internal/cmd/beta/kms/keyring/list/list_test.go @@ -173,6 +173,7 @@ func TestBuildRequest(t *testing.T) { func TestOutputResult(t *testing.T) { tests := []struct { description string + projectId string keyRings []kms.KeyRing outputFormat string projectLabel string @@ -180,18 +181,21 @@ func TestOutputResult(t *testing.T) { }{ { description: "default output", + projectId: uuid.NewString(), keyRings: []kms.KeyRing{}, projectLabel: "my-project", wantErr: false, }, { description: "json output", + projectId: uuid.NewString(), keyRings: []kms.KeyRing{}, outputFormat: print.JSONOutputFormat, wantErr: false, }, { description: "yaml output", + projectId: uuid.NewString(), keyRings: []kms.KeyRing{}, outputFormat: print.YAMLOutputFormat, wantErr: false, @@ -202,7 +206,7 @@ func TestOutputResult(t *testing.T) { p.Cmd = NewCmd(¶ms.CmdParams{Printer: p}) for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { - err := outputResult(p, tt.outputFormat, tt.keyRings) + err := outputResult(p, tt.outputFormat, tt.projectId, tt.keyRings) if (err != nil) != tt.wantErr { t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr) } diff --git a/internal/cmd/beta/kms/version/list/list.go b/internal/cmd/beta/kms/version/list/list.go index 806da6b8d..7a28b9a83 100644 --- a/internal/cmd/beta/kms/version/list/list.go +++ b/internal/cmd/beta/kms/version/list/list.go @@ -64,13 +64,8 @@ func NewCmd(params *params.CmdParams) *cobra.Command { if err != nil { return fmt.Errorf("get Key Versions: %w", err) } - if resp.Versions == nil || len(*resp.Versions) == 0 { - params.Printer.Info("No Key Versions found for project %q in region %q for the key %q\n", model.ProjectId, model.Region, model.KeyId) - return nil - } - keys := *resp.Versions - return outputResult(params.Printer, model.OutputFormat, keys) + return outputResult(params.Printer, model.OutputFormat, model.ProjectId, model.KeyId, *resp.Versions) }, } @@ -106,7 +101,7 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClie return apiClient.ListVersions(ctx, model.ProjectId, model.Region, model.KeyRingId, model.KeyId) } -func outputResult(p *print.Printer, outputFormat string, versions []kms.Version) error { +func outputResult(p *print.Printer, outputFormat, projectId, keyId string, versions []kms.Version) error { switch outputFormat { case print.JSONOutputFormat: details, err := json.MarshalIndent(versions, "", " ") @@ -125,6 +120,10 @@ func outputResult(p *print.Printer, outputFormat string, versions []kms.Version) return nil default: + if len(versions) == 0 { + p.Outputf("No Key Versions found for project %q for the key %q\n", projectId, keyId) + return nil + } table := tables.NewTable() table.SetHeader("ID", "NUMBER", "CREATED AT", "DESTROY DATE", "STATUS") diff --git a/internal/cmd/beta/kms/version/list/list_test.go b/internal/cmd/beta/kms/version/list/list_test.go index 443002d35..3f2172204 100644 --- a/internal/cmd/beta/kms/version/list/list_test.go +++ b/internal/cmd/beta/kms/version/list/list_test.go @@ -230,11 +230,19 @@ func TestBuildRequest(t *testing.T) { func TestOutputResult(t *testing.T) { tests := []struct { description string + projectId string + keyId string versions []kms.Version outputFormat string projectLabel string wantErr bool }{ + { + description: "empty default", + versions: nil, + projectLabel: "my-project", + wantErr: false, + }, { description: "default output", versions: []kms.Version{}, @@ -259,7 +267,7 @@ func TestOutputResult(t *testing.T) { p.Cmd = NewCmd(¶ms.CmdParams{Printer: p}) for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { - err := outputResult(p, tt.outputFormat, tt.versions) + err := outputResult(p, tt.outputFormat, tt.projectId, tt.keyId, tt.versions) if (err != nil) != tt.wantErr { t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr) } diff --git a/internal/cmd/beta/kms/wrappingkey/list/list.go b/internal/cmd/beta/kms/wrappingkey/list/list.go index 6c2163f66..2803a3e89 100644 --- a/internal/cmd/beta/kms/wrappingkey/list/list.go +++ b/internal/cmd/beta/kms/wrappingkey/list/list.go @@ -62,13 +62,8 @@ func NewCmd(params *params.CmdParams) *cobra.Command { if err != nil { return fmt.Errorf("get KMS Wrapping Keys: %w", err) } - if resp.WrappingKeys == nil || len(*resp.WrappingKeys) == 0 { - params.Printer.Info("No Wrapping Keys found for project %q in region %q under the key ring %q\n", model.ProjectId, model.Region, model.KeyRingId) - return nil - } - wrappingKeys := *resp.WrappingKeys - return outputResult(params.Printer, model.OutputFormat, wrappingKeys) + return outputResult(params.Printer, model.OutputFormat, model.ProjectId, model.KeyRingId, *resp.WrappingKeys) }, } return cmd @@ -104,7 +99,7 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClie return req } -func outputResult(p *print.Printer, outputFormat string, wrappingKeys []kms.WrappingKey) error { +func outputResult(p *print.Printer, outputFormat, projectId, keyRingId string, wrappingKeys []kms.WrappingKey) error { switch outputFormat { case print.JSONOutputFormat: details, err := json.MarshalIndent(wrappingKeys, "", " ") @@ -123,6 +118,10 @@ func outputResult(p *print.Printer, outputFormat string, wrappingKeys []kms.Wrap return nil default: + if len(wrappingKeys) == 0 { + p.Outputf("No Wrapping Keys found for project %q under the key ring %q\n", projectId, keyRingId) + return nil + } table := tables.NewTable() table.SetHeader("ID", "NAME", "SCOPE", "ALGORITHM", "EXPIRES AT", "STATUS") diff --git a/internal/cmd/beta/kms/wrappingkey/list/list_test.go b/internal/cmd/beta/kms/wrappingkey/list/list_test.go index d826546b4..74a5facb9 100644 --- a/internal/cmd/beta/kms/wrappingkey/list/list_test.go +++ b/internal/cmd/beta/kms/wrappingkey/list/list_test.go @@ -220,6 +220,8 @@ func TestBuildRequest(t *testing.T) { func TestOutputResult(t *testing.T) { tests := []struct { description string + projectId string + keyRingId string wrappingKeys []kms.WrappingKey outputFormat string projectLabel string @@ -249,7 +251,7 @@ func TestOutputResult(t *testing.T) { p.Cmd = NewCmd(¶ms.CmdParams{Printer: p}) for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { - err := outputResult(p, tt.outputFormat, tt.wrappingKeys) + err := outputResult(p, tt.outputFormat, tt.projectId, tt.keyRingId, tt.wrappingKeys) if (err != nil) != tt.wantErr { t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr) } From b63c6743e50f1530b0fa5e32b8238b23e4ee4512 Mon Sep 17 00:00:00 2001 From: Jan Sternagel Date: Fri, 5 Sep 2025 22:33:07 +0200 Subject: [PATCH 11/52] make test variables constant --- .../cmd/beta/kms/keyring/create/create_test.go | 12 ++++++------ .../cmd/beta/kms/version/destroy/destroy_test.go | 14 +++++++------- .../cmd/beta/kms/version/disable/disable_test.go | 14 +++++++------- .../cmd/beta/kms/version/enable/enable_test.go | 14 +++++++------- .../cmd/beta/kms/version/restore/restore_test.go | 14 +++++++------- 5 files changed, 34 insertions(+), 34 deletions(-) diff --git a/internal/cmd/beta/kms/keyring/create/create_test.go b/internal/cmd/beta/kms/keyring/create/create_test.go index 7b7f8f8b4..02a66cda6 100644 --- a/internal/cmd/beta/kms/keyring/create/create_test.go +++ b/internal/cmd/beta/kms/keyring/create/create_test.go @@ -16,17 +16,17 @@ import ( ) const ( - testRegion = "eu01" + testRegion = "eu01" + testKeyRingName = "my-key-ring" + testDescription = "my-description" ) type testCtxKey struct{} var ( - testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") - testClient = &kms.APIClient{} - testProjectId = uuid.NewString() - testKeyRingName = "my-key-ring" - testDescription = "my-description" + testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") + testClient = &kms.APIClient{} + testProjectId = uuid.NewString() ) // Flags diff --git a/internal/cmd/beta/kms/version/destroy/destroy_test.go b/internal/cmd/beta/kms/version/destroy/destroy_test.go index 65efb6ddd..6e1887714 100644 --- a/internal/cmd/beta/kms/version/destroy/destroy_test.go +++ b/internal/cmd/beta/kms/version/destroy/destroy_test.go @@ -15,18 +15,18 @@ import ( ) const ( - testRegion = "eu02" + testRegion = "eu02" + testVersionNumber = int64(1) ) type testCtxKey struct{} var ( - testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") - testClient = &kms.APIClient{} - testProjectId = uuid.NewString() - testKeyRingId = uuid.NewString() - testKeyId = uuid.NewString() - testVersionNumber = int64(1) + testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") + testClient = &kms.APIClient{} + testProjectId = uuid.NewString() + testKeyRingId = uuid.NewString() + testKeyId = uuid.NewString() ) // Flags diff --git a/internal/cmd/beta/kms/version/disable/disable_test.go b/internal/cmd/beta/kms/version/disable/disable_test.go index 32f651c74..b134c5029 100644 --- a/internal/cmd/beta/kms/version/disable/disable_test.go +++ b/internal/cmd/beta/kms/version/disable/disable_test.go @@ -15,18 +15,18 @@ import ( ) const ( - testRegion = "eu02" + testRegion = "eu02" + testVersionNumber = int64(1) ) type testCtxKey struct{} var ( - testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") - testClient = &kms.APIClient{} - testProjectId = uuid.NewString() - testKeyRingId = uuid.NewString() - testKeyId = uuid.NewString() - testVersionNumber = int64(1) + testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") + testClient = &kms.APIClient{} + testProjectId = uuid.NewString() + testKeyRingId = uuid.NewString() + testKeyId = uuid.NewString() ) // Flags diff --git a/internal/cmd/beta/kms/version/enable/enable_test.go b/internal/cmd/beta/kms/version/enable/enable_test.go index 70a30c67f..ed95e783e 100644 --- a/internal/cmd/beta/kms/version/enable/enable_test.go +++ b/internal/cmd/beta/kms/version/enable/enable_test.go @@ -15,18 +15,18 @@ import ( ) const ( - testRegion = "eu02" + testRegion = "eu02" + testVersionNumber = int64(1) ) type testCtxKey struct{} var ( - testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") - testClient = &kms.APIClient{} - testProjectId = uuid.NewString() - testKeyRingId = uuid.NewString() - testKeyId = uuid.NewString() - testVersionNumber = int64(1) + testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") + testClient = &kms.APIClient{} + testProjectId = uuid.NewString() + testKeyRingId = uuid.NewString() + testKeyId = uuid.NewString() ) // Flags diff --git a/internal/cmd/beta/kms/version/restore/restore_test.go b/internal/cmd/beta/kms/version/restore/restore_test.go index 719bebf67..3fa62cbc9 100644 --- a/internal/cmd/beta/kms/version/restore/restore_test.go +++ b/internal/cmd/beta/kms/version/restore/restore_test.go @@ -15,18 +15,18 @@ import ( ) const ( - testRegion = "eu02" + testRegion = "eu02" + testVersionNumber = int64(1) ) type testCtxKey struct{} var ( - testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") - testClient = &kms.APIClient{} - testProjectId = uuid.NewString() - testKeyRingId = uuid.NewString() - testKeyId = uuid.NewString() - testVersionNumber = int64(1) + testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") + testClient = &kms.APIClient{} + testProjectId = uuid.NewString() + testKeyRingId = uuid.NewString() + testKeyId = uuid.NewString() ) // Flags From f92f4c533de5d5585c895f18a8081b974dacfd28 Mon Sep 17 00:00:00 2001 From: Jan Sternagel Date: Fri, 5 Sep 2025 22:41:21 +0200 Subject: [PATCH 12/52] Can't remove backend yet, due to missing kms v0.5.1 support --- .../cmd/beta/kms/key/create/create_test.go | 20 +++++++++---------- .../kms/wrappingkey/create/create_test.go | 20 +++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/internal/cmd/beta/kms/key/create/create_test.go b/internal/cmd/beta/kms/key/create/create_test.go index e62247fcd..bc9c5dbfd 100644 --- a/internal/cmd/beta/kms/key/create/create_test.go +++ b/internal/cmd/beta/kms/key/create/create_test.go @@ -16,16 +16,7 @@ import ( ) const ( - testRegion = "eu01" -) - -type testCtxKey struct{} - -var ( - testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") - testClient = &kms.APIClient{} - testProjectId = uuid.NewString() - testKeyRingId = uuid.NewString() + testRegion = "eu01" testAlgorithm = "some_rsa_2048" testDisplayName = "my-key" testPurpose = "asymmetric_encrypt_decrypt" @@ -34,6 +25,15 @@ var ( testBackend = "notSoftware" ) +type testCtxKey struct{} + +var ( + testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") + testClient = &kms.APIClient{} + testProjectId = uuid.NewString() + testKeyRingId = uuid.NewString() +) + // Flags func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]string { flagValues := map[string]string{ diff --git a/internal/cmd/beta/kms/wrappingkey/create/create_test.go b/internal/cmd/beta/kms/wrappingkey/create/create_test.go index 6ae2bd384..26dbc5996 100644 --- a/internal/cmd/beta/kms/wrappingkey/create/create_test.go +++ b/internal/cmd/beta/kms/wrappingkey/create/create_test.go @@ -16,16 +16,7 @@ import ( ) const ( - testRegion = "eu01" -) - -type testCtxKey struct{} - -var ( - testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") - testClient = &kms.APIClient{} - testProjectId = uuid.NewString() - testKeyRingId = uuid.NewString() + testRegion = "eu01" testAlgorithm = "some_rsa_2048" testDisplayName = "my-key" testPurpose = "asymmetric_encrypt_decrypt" @@ -33,6 +24,15 @@ var ( testBackend = "notSoftware" ) +type testCtxKey struct{} + +var ( + testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") + testClient = &kms.APIClient{} + testProjectId = uuid.NewString() + testKeyRingId = uuid.NewString() +) + // Flags func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]string { flagValues := map[string]string{ From 07da0b7d95ff3b5a2e024ff30e737513436e76fd Mon Sep 17 00:00:00 2001 From: Jan Sternagel Date: Fri, 5 Sep 2025 22:47:54 +0200 Subject: [PATCH 13/52] linting improvement --- internal/cmd/beta/kms/key/list/list.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/cmd/beta/kms/key/list/list.go b/internal/cmd/beta/kms/key/list/list.go index adecbc958..c1c64f523 100644 --- a/internal/cmd/beta/kms/key/list/list.go +++ b/internal/cmd/beta/kms/key/list/list.go @@ -99,7 +99,7 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClie return req } -func outputResult(p *print.Printer, outputFormat string, projectId, keyRingId string, keys []kms.Key) error { +func outputResult(p *print.Printer, outputFormat, projectId, keyRingId string, keys []kms.Key) error { switch outputFormat { case print.JSONOutputFormat: details, err := json.MarshalIndent(keys, "", " ") From 2f9e6d388b1ae154a9e2c7a6284047394f2850bc Mon Sep 17 00:00:00 2001 From: Jan Sternagel Date: Fri, 5 Sep 2025 22:49:52 +0200 Subject: [PATCH 14/52] generate-docs update --- docs/stackit_beta_kms_key_import.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/stackit_beta_kms_key_import.md b/docs/stackit_beta_kms_key_import.md index 07a32a019..2dbfd2f1c 100644 --- a/docs/stackit_beta_kms_key_import.md +++ b/docs/stackit_beta_kms_key_import.md @@ -40,4 +40,5 @@ stackit beta kms key import [flags] ### SEE ALSO -- [stackit beta kms key](./stackit_beta_kms_key.md) - Manage KMS Keys +* [stackit beta kms key](./stackit_beta_kms_key.md) - Manage KMS Keys + From 2614575166292f809f38c754d09a0e36b9c6941f Mon Sep 17 00:00:00 2001 From: Jan Sternagel Date: Wed, 10 Sep 2025 16:50:29 +0200 Subject: [PATCH 15/52] Upgrade KMS to v1.0.0 --- docs/stackit_beta_kms_key_create.md | 1 - docs/stackit_beta_kms_wrappingkey_create.md | 1 - go.mod | 2 +- go.sum | 4 ++-- internal/cmd/beta/kms/key/create/create.go | 5 ----- internal/cmd/beta/kms/key/create/create_test.go | 7 ------- internal/cmd/beta/kms/wrappingkey/create/create.go | 5 ----- internal/cmd/beta/kms/wrappingkey/create/create_test.go | 7 ------- internal/cmd/beta/kms/wrappingkey/delete/delete.go | 2 -- 9 files changed, 3 insertions(+), 31 deletions(-) diff --git a/docs/stackit_beta_kms_key_create.md b/docs/stackit_beta_kms_key_create.md index e28206dc6..94f7fd3eb 100644 --- a/docs/stackit_beta_kms_key_create.md +++ b/docs/stackit_beta_kms_key_create.md @@ -24,7 +24,6 @@ stackit beta kms key create [flags] ``` --algorithm string En-/Decryption / signing algorithm - --backend string The backend that is responsible for maintaining this key (default "software") --description string Optinal description of the Key -h, --help Help for "stackit beta kms key create" --import-only States whether versions can be created or only imported diff --git a/docs/stackit_beta_kms_wrappingkey_create.md b/docs/stackit_beta_kms_wrappingkey_create.md index ab44e5e63..a8fb90734 100644 --- a/docs/stackit_beta_kms_wrappingkey_create.md +++ b/docs/stackit_beta_kms_wrappingkey_create.md @@ -24,7 +24,6 @@ stackit beta kms wrappingkey create [flags] ``` --algorithm string En-/Decryption algorithm - --backend string The backend that is responsible for maintaining this wrapping key (default "software") --description string Optinal description of the Wrapping Key -h, --help Help for "stackit beta kms wrappingkey create" --key-ring string ID of the KMS Key Ring diff --git a/go.mod b/go.mod index dfc43ff76..4274abe55 100644 --- a/go.mod +++ b/go.mod @@ -238,7 +238,7 @@ require ( github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.14.0 // indirect github.com/spf13/cast v1.7.1 // indirect - github.com/stackitcloud/stackit-sdk-go/services/kms v0.5.1 + github.com/stackitcloud/stackit-sdk-go/services/kms v1.0.0 github.com/stackitcloud/stackit-sdk-go/services/loadbalancer v1.5.1 github.com/stackitcloud/stackit-sdk-go/services/logme v0.25.1 github.com/stackitcloud/stackit-sdk-go/services/mariadb v0.25.1 diff --git a/go.sum b/go.sum index 92f0af662..76b355edc 100644 --- a/go.sum +++ b/go.sum @@ -573,10 +573,10 @@ github.com/stackitcloud/stackit-sdk-go/services/dns v0.17.1 h1:CnhAMLql0MNmAeq4r github.com/stackitcloud/stackit-sdk-go/services/dns v0.17.1/go.mod h1:7Bx85knfNSBxulPdJUFuBePXNee3cO+sOTYnUG6M+iQ= github.com/stackitcloud/stackit-sdk-go/services/git v0.7.1 h1:hkFixFnBcQzU4BSIZFITc8N0gK0pUYk7mk0wdUu5Ki8= github.com/stackitcloud/stackit-sdk-go/services/git v0.7.1/go.mod h1:Ng1EzrRndG3iGXGH90AZJz//wfK+2YOyDwTnTLwX3a4= -github.com/stackitcloud/stackit-sdk-go/services/kms v0.5.1 h1:QWG78oHtX5tjTQSnLpsBSgrYPEf2nDnb8nhE+K3NztA= -github.com/stackitcloud/stackit-sdk-go/services/kms v0.5.1/go.mod h1:KEPVoO21pC4bjy5l0nyhjUJ0+uVwVWb+k2TYrzJ8xYw= github.com/stackitcloud/stackit-sdk-go/services/iaas v0.29.2 h1:BvrbqLi9u0943TTkflPDLGbXgqgVzv7oy8tZHD3q3lg= github.com/stackitcloud/stackit-sdk-go/services/iaas v0.29.2/go.mod h1:b/jgJf7QHdRzU2fmZeJJtu5j0TAevDRghzcn5MyRmOI= +github.com/stackitcloud/stackit-sdk-go/services/kms v1.0.0 h1:zxoOv7Fu+FmdsvTKiKkbmLItrMKfL+QoVtz9ReEF30E= +github.com/stackitcloud/stackit-sdk-go/services/kms v1.0.0/go.mod h1:KEPVoO21pC4bjy5l0nyhjUJ0+uVwVWb+k2TYrzJ8xYw= github.com/stackitcloud/stackit-sdk-go/services/loadbalancer v1.5.1 h1:OdJEs8eOfrzn9tCBDLxIyP8hX50zPfcXNYnRoQX+chs= github.com/stackitcloud/stackit-sdk-go/services/loadbalancer v1.5.1/go.mod h1:11uzaOPCF9SeDHXEGOPMlHDD3J5r2TnvCGUwW9Igq9c= github.com/stackitcloud/stackit-sdk-go/services/logme v0.25.1 h1:hv5WrRU9rN6Jx4OwdOGJRyaQrfA9p1tzEoQK6/CDyoA= diff --git a/internal/cmd/beta/kms/key/create/create.go b/internal/cmd/beta/kms/key/create/create.go index 035dba2dc..160078d2e 100644 --- a/internal/cmd/beta/kms/key/create/create.go +++ b/internal/cmd/beta/kms/key/create/create.go @@ -25,7 +25,6 @@ const ( keyRingIdFlag = "key-ring" algorithmFlag = "algorithm" - backendFlag = "backend" descriptionFlag = "description" displayNameFlag = "name" importOnlyFlag = "import-only" @@ -37,7 +36,6 @@ type inputModel struct { KeyRingId string Algorithm *string - Backend string // Keep "backend" as a variable, but set the default to "software" (see UI) Description *string Name *string ImportOnly bool // Default false @@ -116,7 +114,6 @@ func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { GlobalFlagModel: globalFlags, KeyRingId: flags.FlagToStringValue(p, cmd, keyRingIdFlag), Algorithm: flags.FlagToStringPointer(p, cmd, algorithmFlag), - Backend: flags.FlagWithDefaultToStringValue(p, cmd, backendFlag), Name: flags.FlagToStringPointer(p, cmd, displayNameFlag), Description: flags.FlagToStringPointer(p, cmd, descriptionFlag), ImportOnly: flags.FlagToBoolValue(p, cmd, importOnlyFlag), @@ -147,7 +144,6 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient kmsKeyClient DisplayName: model.Name, Description: model.Description, Algorithm: kms.CreateKeyPayloadGetAlgorithmAttributeType(model.Algorithm), - Backend: kms.CreateKeyPayloadGetBackendAttributeType(&model.Backend), Purpose: kms.CreateKeyPayloadGetPurposeAttributeType(model.Purpose), ImportOnly: &model.ImportOnly, }) @@ -185,7 +181,6 @@ func outputResult(p *print.Printer, outputFormat, projectLabel string, resp *kms func configureFlags(cmd *cobra.Command) { cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS Key Ring") cmd.Flags().String(algorithmFlag, "", "En-/Decryption / signing algorithm") - cmd.Flags().String(backendFlag, "software", "The backend that is responsible for maintaining this key") cmd.Flags().String(displayNameFlag, "", "The display name to distinguish multiple keys") cmd.Flags().String(descriptionFlag, "", "Optinal description of the Key") cmd.Flags().Bool(importOnlyFlag, false, "States whether versions can be created or only imported") diff --git a/internal/cmd/beta/kms/key/create/create_test.go b/internal/cmd/beta/kms/key/create/create_test.go index bc9c5dbfd..69e4df392 100644 --- a/internal/cmd/beta/kms/key/create/create_test.go +++ b/internal/cmd/beta/kms/key/create/create_test.go @@ -22,7 +22,6 @@ const ( testPurpose = "asymmetric_encrypt_decrypt" testDescription = "my key description" testImportOnly = "true" - testBackend = "notSoftware" ) type testCtxKey struct{} @@ -45,7 +44,6 @@ func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]st purposeFlag: testPurpose, descriptionFlag: testDescription, importOnlyFlag: testImportOnly, - backendFlag: testBackend, } for _, mod := range mods { mod(flagValues) @@ -67,7 +65,6 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { Purpose: utils.Ptr(testPurpose), Description: utils.Ptr(testDescription), ImportOnly: true, // Watch out: ImportOnly is not testImportOnly! - Backend: testBackend, } for _, mod := range mods { mod(model) @@ -84,7 +81,6 @@ func fixtureRequest(mods ...func(request *kms.ApiCreateKeyRequest)) kms.ApiCreat Purpose: kms.CreateKeyPayloadGetPurposeAttributeType(utils.Ptr(testPurpose)), Description: utils.Ptr(testDescription), ImportOnly: utils.Ptr(true), - Backend: kms.CreateKeyPayloadGetBackendAttributeType(utils.Ptr(testBackend)), }) for _, mod := range mods { @@ -111,13 +107,11 @@ func TestParseInput(t *testing.T) { flagValues: fixtureFlagValues(func(flagValues map[string]string) { delete(flagValues, descriptionFlag) delete(flagValues, importOnlyFlag) - delete(flagValues, backendFlag) }), isValid: true, expectedModel: fixtureInputModel(func(model *inputModel) { model.Description = nil model.ImportOnly = false - model.Backend = "software" }), }, { @@ -254,7 +248,6 @@ func TestBuildRequest(t *testing.T) { Purpose: kms.CreateKeyPayloadGetPurposeAttributeType(utils.Ptr(testPurpose)), Description: nil, ImportOnly: utils.Ptr(false), - Backend: kms.CreateKeyPayloadGetBackendAttributeType(utils.Ptr(testBackend)), }), }, } diff --git a/internal/cmd/beta/kms/wrappingkey/create/create.go b/internal/cmd/beta/kms/wrappingkey/create/create.go index e10ba647a..7f719f973 100644 --- a/internal/cmd/beta/kms/wrappingkey/create/create.go +++ b/internal/cmd/beta/kms/wrappingkey/create/create.go @@ -27,7 +27,6 @@ const ( keyRingIdFlag = "key-ring" algorithmFlag = "algorithm" - backendFlag = "backend" descriptionFlag = "description" displayNameFlag = "name" purposeFlag = "purpose" @@ -38,7 +37,6 @@ type inputModel struct { KeyRingId string Algorithm *string - Backend string // Keep "backend" as a variable, but set the default to "software" (see UI) Description *string Name *string Purpose *string @@ -125,7 +123,6 @@ func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { GlobalFlagModel: globalFlags, KeyRingId: flags.FlagToStringValue(p, cmd, keyRingIdFlag), Algorithm: flags.FlagToStringPointer(p, cmd, algorithmFlag), - Backend: flags.FlagWithDefaultToStringValue(p, cmd, backendFlag), Name: flags.FlagToStringPointer(p, cmd, displayNameFlag), Description: flags.FlagToStringPointer(p, cmd, descriptionFlag), Purpose: flags.FlagToStringPointer(p, cmd, purposeFlag), @@ -157,7 +154,6 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient kmsWrappingK Description: model.Description, Algorithm: kms.CreateWrappingKeyPayloadGetAlgorithmAttributeType(model.Algorithm), Purpose: kms.CreateWrappingKeyPayloadGetPurposeAttributeType(model.Purpose), - Backend: kms.CreateWrappingKeyPayloadGetBackendAttributeType(&model.Backend), }) return req, nil } @@ -193,7 +189,6 @@ func outputResult(p *print.Printer, outputFormat, projectLabel string, resp *kms func configureFlags(cmd *cobra.Command) { cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS Key Ring") cmd.Flags().String(algorithmFlag, "", "En-/Decryption algorithm") - cmd.Flags().String(backendFlag, "software", "The backend that is responsible for maintaining this wrapping key") cmd.Flags().String(displayNameFlag, "", "The display name to distinguish multiple wrapping keys") cmd.Flags().String(descriptionFlag, "", "Optinal description of the Wrapping Key") cmd.Flags().String(purposeFlag, "", "Purpose of the Wrapping Key. Enum: 'wrap_symmetric_key', 'wrap_asymmetric_key' ") diff --git a/internal/cmd/beta/kms/wrappingkey/create/create_test.go b/internal/cmd/beta/kms/wrappingkey/create/create_test.go index 26dbc5996..4eff07b10 100644 --- a/internal/cmd/beta/kms/wrappingkey/create/create_test.go +++ b/internal/cmd/beta/kms/wrappingkey/create/create_test.go @@ -21,7 +21,6 @@ const ( testDisplayName = "my-key" testPurpose = "asymmetric_encrypt_decrypt" testDescription = "my key description" - testBackend = "notSoftware" ) type testCtxKey struct{} @@ -43,7 +42,6 @@ func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]st displayNameFlag: testDisplayName, purposeFlag: testPurpose, descriptionFlag: testDescription, - backendFlag: testBackend, } for _, mod := range mods { mod(flagValues) @@ -64,7 +62,6 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { Name: utils.Ptr(testDisplayName), Purpose: utils.Ptr(testPurpose), Description: utils.Ptr(testDescription), - Backend: testBackend, } for _, mod := range mods { mod(model) @@ -80,7 +77,6 @@ func fixtureRequest(mods ...func(request *kms.ApiCreateWrappingKeyRequest)) kms. DisplayName: utils.Ptr(testDisplayName), Purpose: kms.CreateWrappingKeyPayloadGetPurposeAttributeType(utils.Ptr(testPurpose)), Description: utils.Ptr(testDescription), - Backend: kms.CreateWrappingKeyPayloadGetBackendAttributeType(utils.Ptr(testBackend)), }) for _, mod := range mods { @@ -106,12 +102,10 @@ func TestParseInput(t *testing.T) { description: "optional flags omitted", flagValues: fixtureFlagValues(func(flagValues map[string]string) { delete(flagValues, descriptionFlag) - delete(flagValues, backendFlag) }), isValid: true, expectedModel: fixtureInputModel(func(model *inputModel) { model.Description = nil - model.Backend = "software" }), }, { @@ -245,7 +239,6 @@ func TestBuildRequest(t *testing.T) { Algorithm: kms.CreateWrappingKeyPayloadGetAlgorithmAttributeType(utils.Ptr(testAlgorithm)), DisplayName: utils.Ptr(testDisplayName), Purpose: kms.CreateWrappingKeyPayloadGetPurposeAttributeType(utils.Ptr(testPurpose)), - Backend: kms.CreateWrappingKeyPayloadGetBackendAttributeType(utils.Ptr(testBackend)), }), }, } diff --git a/internal/cmd/beta/kms/wrappingkey/delete/delete.go b/internal/cmd/beta/kms/wrappingkey/delete/delete.go index 1f5224a0d..7b94185cc 100644 --- a/internal/cmd/beta/kms/wrappingkey/delete/delete.go +++ b/internal/cmd/beta/kms/wrappingkey/delete/delete.go @@ -76,8 +76,6 @@ func NewCmd(params *params.CmdParams) *cobra.Command { } // Wait for async operation not relevant. Wrapping key deletion is synchronous - // https://pkg.go.dev/github.com/stackitcloud/stackit-sdk-go/services/kms@v0.5.1/wait - params.Printer.Info("Deleted wrapping key %q\n", wrappingKeyName) return nil }, From b925f4e8ff21c7e190b8a6dfdbe9d5c7e84163f5 Mon Sep 17 00:00:00 2001 From: Jan Sternagel Date: Thu, 11 Sep 2025 14:48:04 +0200 Subject: [PATCH 16/52] fix spelling --- internal/cmd/beta/kms/key/key.go | 2 +- internal/cmd/beta/kms/key/list/list.go | 11 ++++---- internal/cmd/beta/kms/keyring/keyring.go | 4 +-- internal/cmd/beta/kms/keyring/list/list.go | 16 ++++++------ internal/cmd/beta/kms/version/list/list.go | 16 ++++++------ internal/cmd/beta/kms/version/version.go | 4 +-- .../cmd/beta/kms/wrappingkey/create/create.go | 26 +++++++++---------- .../cmd/beta/kms/wrappingkey/list/list.go | 17 ++++++------ .../cmd/beta/kms/wrappingkey/wrappingkey.go | 6 ++--- 9 files changed, 50 insertions(+), 52 deletions(-) diff --git a/internal/cmd/beta/kms/key/key.go b/internal/cmd/beta/kms/key/key.go index 562207eca..35cd46340 100644 --- a/internal/cmd/beta/kms/key/key.go +++ b/internal/cmd/beta/kms/key/key.go @@ -18,7 +18,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { cmd := &cobra.Command{ Use: "key", Short: "Manage KMS Keys", - Long: "Provides CRUD functionality for Key operations inside the KMS", + Long: "Provides functionality for key operations inside the KMS", Args: args.NoArgs, Run: utils.CmdHelp, } diff --git a/internal/cmd/beta/kms/key/list/list.go b/internal/cmd/beta/kms/key/list/list.go index c1c64f523..51b7a7345 100644 --- a/internal/cmd/beta/kms/key/list/list.go +++ b/internal/cmd/beta/kms/key/list/list.go @@ -31,15 +31,15 @@ type inputModel struct { func NewCmd(params *params.CmdParams) *cobra.Command { cmd := &cobra.Command{ Use: fmt.Sprintf("list %s", keyRingIdArg), - Short: "Lists all KMS Keys", - Long: "Lists all KMS Keys inside a key ring.", + Short: "List all KMS keys", + Long: "List all KMS keys inside a key ring.", Args: args.SingleArg(keyRingIdArg, utils.ValidateUUID), Example: examples.Build( examples.NewExample( - `List all KMS Keys for the key ring "xxx"`, + `List all KMS keys for the key ring "xxx"`, "$ stackit beta kms key list xxx"), examples.NewExample( - `List all KMS Keys in JSON format`, + `List all KMS keys in JSON format`, "$ stackit beta kms key list xxx --output-format json"), ), RunE: func(cmd *cobra.Command, args []string) error { @@ -119,7 +119,7 @@ func outputResult(p *print.Printer, outputFormat, projectId, keyRingId string, k return nil default: if len(keys) == 0 { - p.Outputf("No Keys found for project %q under the key ring %q\n", projectId, keyRingId) + p.Outputf("No keys found for project %q under the key ring %q\n", projectId, keyRingId) return nil } table := tables.NewTable() @@ -132,7 +132,6 @@ func outputResult(p *print.Printer, outputFormat, projectId, keyRingId string, k utils.PtrString(key.DisplayName), utils.PtrString(key.Purpose), utils.PtrString(key.Algorithm), - // utils.PtrString(wrappingKeys.CreatedAt), utils.PtrString(key.DeletionDate), utils.PtrString(key.State), ) diff --git a/internal/cmd/beta/kms/keyring/keyring.go b/internal/cmd/beta/kms/keyring/keyring.go index 27c31f1e9..7a42ce131 100644 --- a/internal/cmd/beta/kms/keyring/keyring.go +++ b/internal/cmd/beta/kms/keyring/keyring.go @@ -14,8 +14,8 @@ import ( func NewCmd(params *params.CmdParams) *cobra.Command { cmd := &cobra.Command{ Use: "keyring", - Short: "Manage KMS Keyrings", - Long: "Provides functionality for Keyring operations inside the KMS", + Short: "Manage KMS key rings", + Long: "Provides functionality for key ring operations inside the KMS", Args: args.NoArgs, Run: utils.CmdHelp, } diff --git a/internal/cmd/beta/kms/keyring/list/list.go b/internal/cmd/beta/kms/keyring/list/list.go index a1fb00624..ea8d96b6b 100644 --- a/internal/cmd/beta/kms/keyring/list/list.go +++ b/internal/cmd/beta/kms/keyring/list/list.go @@ -26,15 +26,15 @@ type inputModel struct { func NewCmd(params *params.CmdParams) *cobra.Command { cmd := &cobra.Command{ Use: "list", - Short: "Lists all KMS Keyrings", - Long: "Lists all KMS Keyrings.", + Short: "Lists all KMS key rings", + Long: "Lists all KMS key rings.", Args: args.NoArgs, Example: examples.Build( examples.NewExample( - `List all KMS Keyrings`, + `List all KMS key rings`, "$ stackit beta kms keyring list"), examples.NewExample( - `List all KMS Keyrings in JSON format`, + `List all KMS key rings in JSON format`, "$ stackit beta kms keyring list --output-format json"), ), RunE: func(cmd *cobra.Command, _ []string) error { @@ -54,7 +54,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { req := buildRequest(ctx, model, apiClient) resp, err := req.Execute() if err != nil { - return fmt.Errorf("get KMS Keyrings: %w", err) + return fmt.Errorf("get KMS key rings: %w", err) } return outputResult(params.Printer, model.OutputFormat, model.ProjectId, *resp.KeyRings) @@ -96,7 +96,7 @@ func outputResult(p *print.Printer, outputFormat, projectId string, keyRings []k case print.JSONOutputFormat: details, err := json.MarshalIndent(keyRings, "", " ") if err != nil { - return fmt.Errorf("marshal KMS Keyrings list: %w", err) + return fmt.Errorf("marshal KMS key rings list: %w", err) } p.Outputln(string(details)) @@ -104,14 +104,14 @@ func outputResult(p *print.Printer, outputFormat, projectId string, keyRings []k case print.YAMLOutputFormat: details, err := yaml.MarshalWithOptions(keyRings, yaml.IndentSequence(true), yaml.UseJSONMarshaler()) if err != nil { - return fmt.Errorf("marshal KMS Keyrings list: %w", err) + return fmt.Errorf("marshal KMS key rings list: %w", err) } p.Outputln(string(details)) return nil default: if len(keyRings) == 0 { - p.Outputf("No Keyrings found for project %q\n", projectId) + p.Outputf("No key rings found for project %q\n", projectId) return nil } diff --git a/internal/cmd/beta/kms/version/list/list.go b/internal/cmd/beta/kms/version/list/list.go index 7a28b9a83..ea50bae62 100644 --- a/internal/cmd/beta/kms/version/list/list.go +++ b/internal/cmd/beta/kms/version/list/list.go @@ -34,8 +34,8 @@ type inputModel struct { func NewCmd(params *params.CmdParams) *cobra.Command { cmd := &cobra.Command{ Use: "list", - Short: "Lists all Key Versions", - Long: "Lists all versions of a given key.", + Short: "List all key versions", + Long: "List all versions of a given key.", Args: args.NoArgs, Example: examples.Build( examples.NewExample( @@ -62,7 +62,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { req := buildRequest(ctx, model, apiClient) resp, err := req.Execute() if err != nil { - return fmt.Errorf("get Key Versions: %w", err) + return fmt.Errorf("get key version: %w", err) } return outputResult(params.Printer, model.OutputFormat, model.ProjectId, model.KeyId, *resp.Versions) @@ -106,7 +106,7 @@ func outputResult(p *print.Printer, outputFormat, projectId, keyId string, versi case print.JSONOutputFormat: details, err := json.MarshalIndent(versions, "", " ") if err != nil { - return fmt.Errorf("marshal Key Versions list: %w", err) + return fmt.Errorf("marshal key versions list: %w", err) } p.Outputln(string(details)) @@ -114,14 +114,14 @@ func outputResult(p *print.Printer, outputFormat, projectId, keyId string, versi case print.YAMLOutputFormat: details, err := yaml.MarshalWithOptions(versions, yaml.IndentSequence(true), yaml.UseJSONMarshaler()) if err != nil { - return fmt.Errorf("marshal Key Versions list: %w", err) + return fmt.Errorf("marshal key versions list: %w", err) } p.Outputln(string(details)) return nil default: if len(versions) == 0 { - p.Outputf("No Key Versions found for project %q for the key %q\n", projectId, keyId) + p.Outputf("No key versions found for project %q for the key %q\n", projectId, keyId) return nil } table := tables.NewTable() @@ -148,8 +148,8 @@ func outputResult(p *print.Printer, outputFormat, projectId, keyId string, versi } func configureFlags(cmd *cobra.Command) { - cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS Key Ring") - cmd.Flags().Var(flags.UUIDFlag(), keyIdFlag, "ID of the Key") + cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS key ring") + cmd.Flags().Var(flags.UUIDFlag(), keyIdFlag, "ID of the key") err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, keyIdFlag) cobra.CheckErr(err) diff --git a/internal/cmd/beta/kms/version/version.go b/internal/cmd/beta/kms/version/version.go index 47271fcd3..39c90e5c8 100644 --- a/internal/cmd/beta/kms/version/version.go +++ b/internal/cmd/beta/kms/version/version.go @@ -16,8 +16,8 @@ import ( func NewCmd(params *params.CmdParams) *cobra.Command { cmd := &cobra.Command{ Use: "version", - Short: "Manage KMS Key versions", - Long: "Provides CRUD functionality for Key Version operations inside the KMS", + Short: "Manage KMS key versions", + Long: "Provides functionality for key version operations inside the KMS", Args: args.NoArgs, Run: utils.CmdHelp, } diff --git a/internal/cmd/beta/kms/wrappingkey/create/create.go b/internal/cmd/beta/kms/wrappingkey/create/create.go index 7f719f973..3a4009b90 100644 --- a/internal/cmd/beta/kms/wrappingkey/create/create.go +++ b/internal/cmd/beta/kms/wrappingkey/create/create.go @@ -45,15 +45,15 @@ type inputModel struct { func NewCmd(params *params.CmdParams) *cobra.Command { cmd := &cobra.Command{ Use: "create", - Short: "Creates a KMS Wrapping Key", - Long: "Creates a KMS Wrapping Key.", + Short: "Creates a KMS wrapping key", + Long: "Creates a KMS wrapping key.", Args: args.NoArgs, Example: examples.Build( examples.NewExample( - `Create a Symmetric KMS Wrapping Key`, + `Create a Symmetric KMS wrapping key`, `$ stakit beta kms wrappingkey create --key-ring "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-wrapping-key-name" --purpose "wrap_symmetric_key"`), examples.NewExample( - `Create an Asymmetric KMS Wrapping Key with a description`, + `Create an Asymmetric KMS wrapping key with a description`, `$ stakit beta kms wrappingkey create --key-ring "my-keyring-id" --algorithm "hmac_sha256" --name "my-wrapping-key-name" --description "my-description" --purpose "wrap_asymmetric_key"`), ), RunE: func(cmd *cobra.Command, _ []string) error { @@ -76,7 +76,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { } if !model.AssumeYes { - prompt := fmt.Sprintf("Are you sure you want to create a KMS Wrapping Key for project %q?", projectLabel) + prompt := fmt.Sprintf("Are you sure you want to create a KMS wrapping key for project %q?", projectLabel) err = params.Printer.PromptForConfirmation(prompt) if err != nil { return err @@ -91,7 +91,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { wrappingKey, err := req.Execute() if err != nil { - return fmt.Errorf("create KMS Wrapping Key: %w", err) + return fmt.Errorf("create KMS wrapping key: %w", err) } // Wait for async operation, if async mode not enabled @@ -100,7 +100,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { s.Start("Creating instance") _, err = wait.CreateWrappingKeyWaitHandler(ctx, apiClient, model.ProjectId, model.Region, *wrappingKey.KeyRingId, *wrappingKey.Id).WaitWithContext(ctx) if err != nil { - return fmt.Errorf("wait for KMS Wrapping Key creation: %w", err) + return fmt.Errorf("wait for KMS wrapping key creation: %w", err) } s.Stop() } @@ -167,7 +167,7 @@ func outputResult(p *print.Printer, outputFormat, projectLabel string, resp *kms case print.JSONOutputFormat: details, err := json.MarshalIndent(resp, "", " ") if err != nil { - return fmt.Errorf("marshal KMS Wrapping Key: %w", err) + return fmt.Errorf("marshal KMS wrapping key: %w", err) } p.Outputln(string(details)) return nil @@ -175,23 +175,23 @@ func outputResult(p *print.Printer, outputFormat, projectLabel string, resp *kms case print.YAMLOutputFormat: details, err := yaml.MarshalWithOptions(resp, yaml.IndentSequence(true), yaml.UseJSONMarshaler()) if err != nil { - return fmt.Errorf("marshal KMS Wrapping Key: %w", err) + return fmt.Errorf("marshal KMS wrapping key: %w", err) } p.Outputln(string(details)) return nil default: - p.Outputf("Created Wrapping Key for project %q. Wrapping Key ID: %s\n", projectLabel, utils.PtrString(resp.Id)) + p.Outputf("Created wrapping key for project %q. wrapping key ID: %s\n", projectLabel, utils.PtrString(resp.Id)) return nil } } func configureFlags(cmd *cobra.Command) { - cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS Key Ring") + cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS key ring") cmd.Flags().String(algorithmFlag, "", "En-/Decryption algorithm") cmd.Flags().String(displayNameFlag, "", "The display name to distinguish multiple wrapping keys") - cmd.Flags().String(descriptionFlag, "", "Optinal description of the Wrapping Key") - cmd.Flags().String(purposeFlag, "", "Purpose of the Wrapping Key. Enum: 'wrap_symmetric_key', 'wrap_asymmetric_key' ") + cmd.Flags().String(descriptionFlag, "", "Optional description of the wrapping key") + cmd.Flags().String(purposeFlag, "", "Purpose of the wrapping key. Enum: 'wrap_symmetric_key', 'wrap_asymmetric_key' ") err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, algorithmFlag, purposeFlag, displayNameFlag) cobra.CheckErr(err) diff --git a/internal/cmd/beta/kms/wrappingkey/list/list.go b/internal/cmd/beta/kms/wrappingkey/list/list.go index 2803a3e89..b0eebe2e3 100644 --- a/internal/cmd/beta/kms/wrappingkey/list/list.go +++ b/internal/cmd/beta/kms/wrappingkey/list/list.go @@ -31,16 +31,15 @@ type inputModel struct { func NewCmd(params *params.CmdParams) *cobra.Command { cmd := &cobra.Command{ Use: fmt.Sprintf("list %s", keyRingIdArg), - Short: "Lists all KMS Wrapping Keys", - Long: "Lists all KMS Wrapping Keys inside a key ring.", + Short: "Lists all KMS wrapping keys", + Long: "Lists all KMS wrapping keys inside a key ring.", Args: args.SingleArg(keyRingIdArg, utils.ValidateUUID), Example: examples.Build( - // Enforce a specific region for the KMS examples.NewExample( - `List all KMS Wrapping Keys for the key ring "xxx"`, + `List all KMS wrapping keys for the key ring "xxx"`, "$ stackit beta kms wrappingkeys list xxx"), examples.NewExample( - `List all KMS Wrapping Keys in JSON format`, + `List all KMS wrapping keys in JSON format`, "$ stackit beta kms wrappingkeys list xxx --output-format json"), ), RunE: func(cmd *cobra.Command, args []string) error { @@ -60,7 +59,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { req := buildRequest(ctx, model, apiClient) resp, err := req.Execute() if err != nil { - return fmt.Errorf("get KMS Wrapping Keys: %w", err) + return fmt.Errorf("get KMS wrapping keys: %w", err) } return outputResult(params.Printer, model.OutputFormat, model.ProjectId, model.KeyRingId, *resp.WrappingKeys) @@ -104,7 +103,7 @@ func outputResult(p *print.Printer, outputFormat, projectId, keyRingId string, w case print.JSONOutputFormat: details, err := json.MarshalIndent(wrappingKeys, "", " ") if err != nil { - return fmt.Errorf("marshal KMS Wrapping Keys list: %w", err) + return fmt.Errorf("marshal KMS wrapping keys list: %w", err) } p.Outputln(string(details)) @@ -112,14 +111,14 @@ func outputResult(p *print.Printer, outputFormat, projectId, keyRingId string, w case print.YAMLOutputFormat: details, err := yaml.MarshalWithOptions(wrappingKeys, yaml.IndentSequence(true), yaml.UseJSONMarshaler()) if err != nil { - return fmt.Errorf("marshal KMS Wrapping Keys list: %w", err) + return fmt.Errorf("marshal KMS wrapping keys list: %w", err) } p.Outputln(string(details)) return nil default: if len(wrappingKeys) == 0 { - p.Outputf("No Wrapping Keys found for project %q under the key ring %q\n", projectId, keyRingId) + p.Outputf("No wrapping keys found for project %q under the key ring %q\n", projectId, keyRingId) return nil } table := tables.NewTable() diff --git a/internal/cmd/beta/kms/wrappingkey/wrappingkey.go b/internal/cmd/beta/kms/wrappingkey/wrappingkey.go index 474df3487..ab62f221d 100644 --- a/internal/cmd/beta/kms/wrappingkey/wrappingkey.go +++ b/internal/cmd/beta/kms/wrappingkey/wrappingkey.go @@ -13,9 +13,9 @@ import ( func NewCmd(params *params.CmdParams) *cobra.Command { cmd := &cobra.Command{ - Use: "wrappingkey", - Short: "Manage KMS Wrapping Keys", - Long: "Provides CRUD functionality for Wrapping Key operations inside the KMS", + Use: "wrapping-key", + Short: "Manage KMS wrapping keys", + Long: "Provides CRUD functionality for wrapping key operations inside the KMS", Args: args.NoArgs, Run: utils.CmdHelp, } From 6581f82fb0c4babfab8a71580abb0bb6956859c1 Mon Sep 17 00:00:00 2001 From: Jan Sternagel Date: Thu, 11 Sep 2025 14:48:37 +0200 Subject: [PATCH 17/52] added wait for key creation --- internal/cmd/beta/kms/key/create/create.go | 40 ++++++++++++++-------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/internal/cmd/beta/kms/key/create/create.go b/internal/cmd/beta/kms/key/create/create.go index 160078d2e..ce63e45c9 100644 --- a/internal/cmd/beta/kms/key/create/create.go +++ b/internal/cmd/beta/kms/key/create/create.go @@ -11,6 +11,7 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/args" cliErr "github.com/stackitcloud/stackit-cli/internal/pkg/errors" "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/client" + "github.com/stackitcloud/stackit-cli/internal/pkg/spinner" "github.com/stackitcloud/stackit-cli/internal/pkg/examples" "github.com/stackitcloud/stackit-cli/internal/pkg/flags" @@ -19,6 +20,7 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/projectname" "github.com/stackitcloud/stackit-cli/internal/pkg/utils" "github.com/stackitcloud/stackit-sdk-go/services/kms" + "github.com/stackitcloud/stackit-sdk-go/services/kms/wait" ) const ( @@ -45,16 +47,16 @@ type inputModel struct { func NewCmd(params *params.CmdParams) *cobra.Command { cmd := &cobra.Command{ Use: "create", - Short: "Creates a KMS Key", - Long: "Creates a KMS Key.", + Short: "Creates a KMS key", + Long: "Creates a KMS key.", Args: args.NoArgs, Example: examples.Build( examples.NewExample( - `Create a Symmetric KMS Key`, - `$ stakit beta kms key create --key-ring "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-key-name" --purpose "symmetric_encrypt_decrypt"`), + `Create a Symmetric KMS key`, + `$ stackit beta kms key create --key-ring "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-key-name" --purpose "symmetric_encrypt_decrypt"`), examples.NewExample( - `Create a Message Authentication KMS Key`, - `$ stakit beta kms key create --key-ring "my-keyring-id" --algorithm "hmac_sha512" --name "my-key-name" --purpose "message_authentication_code"`), + `Create a Message Authentication KMS key`, + `$ stackit beta kms key create --key-ring "my-keyring-id" --algorithm "hmac_sha512" --name "my-key-name" --purpose "message_authentication_code"`), ), RunE: func(cmd *cobra.Command, _ []string) error { ctx := context.Background() @@ -91,10 +93,20 @@ func NewCmd(params *params.CmdParams) *cobra.Command { key, err := req.Execute() if err != nil { - return fmt.Errorf("create KMS Key: %w", err) + return fmt.Errorf("create KMS key: %w", err) + } + + // Wait for async operation, if async mode not enabled + if !model.Async { + s := spinner.New(params.Printer) + s.Start("Creating key") + _, err = wait.CreateOrUpdateKeyWaitHandler(ctx, apiClient, model.ProjectId, model.Region, model.KeyRingId, *key.Id).WaitWithContext(ctx) + if err != nil { + return fmt.Errorf("wait for KMS key creation: %w", err) + } + s.Stop() } - // No wait exists for the key creation return outputResult(params.Printer, model.OutputFormat, projectLabel, key) }, } @@ -159,7 +171,7 @@ func outputResult(p *print.Printer, outputFormat, projectLabel string, resp *kms case print.JSONOutputFormat: details, err := json.MarshalIndent(resp, "", " ") if err != nil { - return fmt.Errorf("marshal KMS Key: %w", err) + return fmt.Errorf("marshal KMS key: %w", err) } p.Outputln(string(details)) return nil @@ -167,24 +179,24 @@ func outputResult(p *print.Printer, outputFormat, projectLabel string, resp *kms case print.YAMLOutputFormat: details, err := yaml.MarshalWithOptions(resp, yaml.IndentSequence(true), yaml.UseJSONMarshaler()) if err != nil { - return fmt.Errorf("marshal KMS Key: %w", err) + return fmt.Errorf("marshal KMS key: %w", err) } p.Outputln(string(details)) return nil default: - p.Outputf("Created Key for project %q. Key ID: %s\n", projectLabel, utils.PtrString(resp.Id)) + p.Outputf("Created key for project %q. key ID: %s\n", projectLabel, utils.PtrString(resp.Id)) return nil } } func configureFlags(cmd *cobra.Command) { - cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS Key Ring") + cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS key ring") cmd.Flags().String(algorithmFlag, "", "En-/Decryption / signing algorithm") cmd.Flags().String(displayNameFlag, "", "The display name to distinguish multiple keys") - cmd.Flags().String(descriptionFlag, "", "Optinal description of the Key") + cmd.Flags().String(descriptionFlag, "", "Optional description of the key") cmd.Flags().Bool(importOnlyFlag, false, "States whether versions can be created or only imported") - cmd.Flags().String(purposeFlag, "", "Purpose of the Key. Enum: 'symmetric_encrypt_decrypt', 'asymmetric_encrypt_decrypt', 'message_authentication_code', 'asymmetric_sign_verify' ") + cmd.Flags().String(purposeFlag, "", "Purpose of the key. Enum: 'symmetric_encrypt_decrypt', 'asymmetric_encrypt_decrypt', 'message_authentication_code', 'asymmetric_sign_verify' ") err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, algorithmFlag, purposeFlag, displayNameFlag) cobra.CheckErr(err) From 26490c959a3a529dda3c3832f7c56b757d6d8ac6 Mon Sep 17 00:00:00 2001 From: Jan Sternagel Date: Thu, 11 Sep 2025 14:49:34 +0200 Subject: [PATCH 18/52] removed uuid validation in parseInput --- internal/cmd/beta/kms/key/delete/delete.go | 27 ++++------------ .../cmd/beta/kms/key/importKey/importKey.go | 25 +++++++-------- internal/cmd/beta/kms/key/rotate/rotate.go | 32 ++++++------------- 3 files changed, 29 insertions(+), 55 deletions(-) diff --git a/internal/cmd/beta/kms/key/delete/delete.go b/internal/cmd/beta/kms/key/delete/delete.go index 8bd1f2a09..d45d11391 100644 --- a/internal/cmd/beta/kms/key/delete/delete.go +++ b/internal/cmd/beta/kms/key/delete/delete.go @@ -18,7 +18,6 @@ import ( kmsUtils "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/utils" "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/client" - "github.com/stackitcloud/stackit-cli/internal/pkg/utils" "github.com/stackitcloud/stackit-sdk-go/services/kms" ) @@ -36,12 +35,12 @@ type inputModel struct { func NewCmd(params *params.CmdParams) *cobra.Command { cmd := &cobra.Command{ Use: "delete", - Short: "Deletes a KMS Key", - Long: "Deletes a KMS Key inside a specific Key Ring.", + Short: "Deletes a KMS key", + Long: "Deletes a KMS key inside a specific key ring.", Args: args.NoArgs, Example: examples.Build( examples.NewExample( - `Delete a KMS Key "my-key-id" inside the Key Ring "my-key-ring-id"`, + `Delete a KMS key "my-key-id" inside the key ring "my-key-ring-id"`, `$ stackit beta kms keyring delete --key-ring "my-key-ring-id" --key "my-key-id"`), ), RunE: func(cmd *cobra.Command, _ []string) error { @@ -75,7 +74,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { req := buildRequest(ctx, model, apiClient) err = req.Execute() if err != nil { - return fmt.Errorf("delete KMS Key: %w", err) + return fmt.Errorf("delete KMS key: %w", err) } // Don't wait for a month until the deletion was performed. @@ -99,22 +98,10 @@ func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { return nil, &errors.ProjectIdError{} } - keyRingId := flags.FlagToStringValue(p, cmd, keyRingIdFlag) - keyId := flags.FlagToStringValue(p, cmd, keyIdFlag) - - // Validate the uuid format of the IDs - errKeyRing := utils.ValidateUUID(keyRingId) - errKey := utils.ValidateUUID(keyId) - if errKeyRing != nil || errKey != nil { - return nil, &errors.DSAInputPlanError{ - Cmd: cmd, - } - } - model := inputModel{ GlobalFlagModel: globalFlags, - KeyRingId: keyRingId, - KeyId: keyId, + KeyRingId: flags.FlagToStringValue(p, cmd, keyRingIdFlag), + KeyId: flags.FlagToStringValue(p, cmd, keyIdFlag), } if p.IsVerbosityDebug() { @@ -182,7 +169,7 @@ func outputResult(p *print.Printer, outputFormat, keyId, keyName string, deletio return nil default: - p.Outputf("Deletion of KMS Key %q scheduled successfully for the deletion date: %q\n", keyName, deletionDate) + p.Outputf("Deletion of KMS key %q scheduled successfully for the deletion date: %q\n", keyName, deletionDate) return nil } } diff --git a/internal/cmd/beta/kms/key/importKey/importKey.go b/internal/cmd/beta/kms/key/importKey/importKey.go index 35bc870c0..1603b983d 100644 --- a/internal/cmd/beta/kms/key/importKey/importKey.go +++ b/internal/cmd/beta/kms/key/importKey/importKey.go @@ -41,12 +41,12 @@ type inputModel struct { func NewCmd(params *params.CmdParams) *cobra.Command { cmd := &cobra.Command{ Use: "import", - Short: "Import a KMS Key Version", + Short: "Import a KMS key", Long: "Import a new version to the given KMS key.", Args: args.NoArgs, Example: examples.Build( examples.NewExample( - `Import a new version for the given KMS Key "my-key"`, + `Import a new version for the given KMS key "my-key"`, `$ stakit beta kms key import --key-ring "my-keyring-id" --key "my-key-id" --wrapped-key "base64-encoded-wrapped-key-material" --wrapping-key-id "my-wrapping-key-id"`), ), RunE: func(cmd *cobra.Command, _ []string) error { @@ -64,17 +64,17 @@ func NewCmd(params *params.CmdParams) *cobra.Command { keyName, err := kmsUtils.GetKeyName(ctx, apiClient, model.ProjectId, model.Region, model.KeyRingId, model.KeyId) if err != nil { - params.Printer.Debug(print.ErrorLevel, "get Key name: %v", err) + params.Printer.Debug(print.ErrorLevel, "get key name: %v", err) keyName = model.KeyId } keyRingName, err := kmsUtils.GetKeyRingName(ctx, apiClient, model.ProjectId, model.KeyRingId, model.Region) if err != nil { - params.Printer.Debug(print.ErrorLevel, "get Key Ring name: %v", err) + params.Printer.Debug(print.ErrorLevel, "get key ring name: %v", err) keyRingName = model.KeyRingId } if !model.AssumeYes { - prompt := fmt.Sprintf("Are you sure you want to import a new version for the KMS Key %q inside the Key Ring %q?", keyName, keyRingName) + prompt := fmt.Sprintf("Are you sure you want to import a new version for the KMS Key %q inside the key ring %q?", keyName, keyRingName) err = params.Printer.PromptForConfirmation(prompt) if err != nil { return err @@ -89,10 +89,9 @@ func NewCmd(params *params.CmdParams) *cobra.Command { keyVersion, err := req.Execute() if err != nil { - return fmt.Errorf("import KMS Key: %w", err) + return fmt.Errorf("import KMS key: %w", err) } - // No wait exists for the wrapped key import return outputResult(params.Printer, model.OutputFormat, keyRingName, keyName, keyVersion) }, } @@ -160,7 +159,7 @@ func outputResult(p *print.Printer, outputFormat, keyRingName, keyName string, r case print.JSONOutputFormat: details, err := json.MarshalIndent(resp, "", " ") if err != nil { - return fmt.Errorf("marshal KMS Key: %w", err) + return fmt.Errorf("marshal KMS key: %w", err) } p.Outputln(string(details)) return nil @@ -168,22 +167,22 @@ func outputResult(p *print.Printer, outputFormat, keyRingName, keyName string, r case print.YAMLOutputFormat: details, err := yaml.MarshalWithOptions(resp, yaml.IndentSequence(true), yaml.UseJSONMarshaler()) if err != nil { - return fmt.Errorf("marshal KMS Key: %w", err) + return fmt.Errorf("marshal KMS key: %w", err) } p.Outputln(string(details)) return nil default: - p.Outputf("Imported a new version for the Key %q inside the Key Ring %q\n", keyName, keyRingName) + p.Outputf("Imported a new version for the key %q inside the key ring %q\n", keyName, keyRingName) return nil } } func configureFlags(cmd *cobra.Command) { - cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS Key Ring") - cmd.Flags().Var(flags.UUIDFlag(), keyIdFlag, "ID of the KMS Key") + cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS key ring") + cmd.Flags().Var(flags.UUIDFlag(), keyIdFlag, "ID of the KMS key") cmd.Flags().String(wrappedKeyFlag, "", "The wrapped key material that has to be imported. Encoded in base64") - cmd.Flags().Var(flags.UUIDFlag(), wrappingKeyIdFlag, "he unique id of the wrapping key the key material has been wrapped with") + cmd.Flags().Var(flags.UUIDFlag(), wrappingKeyIdFlag, "The unique id of the wrapping key the key material has been wrapped with") err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, keyIdFlag, wrappedKeyFlag, wrappingKeyIdFlag) cobra.CheckErr(err) diff --git a/internal/cmd/beta/kms/key/rotate/rotate.go b/internal/cmd/beta/kms/key/rotate/rotate.go index 7ae32d03e..e38c07ae3 100644 --- a/internal/cmd/beta/kms/key/rotate/rotate.go +++ b/internal/cmd/beta/kms/key/rotate/rotate.go @@ -40,8 +40,8 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Args: args.NoArgs, Example: examples.Build( examples.NewExample( - `Rotate a KMS Key "my-key-id" and increase it's version inside the Key Ring "my-key-ring-id".`, - `$ stackit beta kms keyring rotate --key-ring "my-key-ring-id" --key "my-key-id"`), + `Rotate a KMS key "my-key-id" and increase it's version inside the key ring "my-key-ring-id".`, + `$ stackit beta kms key rotate --key-ring "my-key-ring-id" --key "my-key-id"`), ), RunE: func(cmd *cobra.Command, _ []string) error { ctx := context.Background() @@ -74,7 +74,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { req := buildRequest(ctx, model, apiClient) resp, err := req.Execute() if err != nil { - return fmt.Errorf("rotate KMS Key: %w", err) + return fmt.Errorf("rotate KMS key: %w", err) } return outputResult(params.Printer, model.OutputFormat, resp) @@ -91,22 +91,10 @@ func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { return nil, &errors.ProjectIdError{} } - keyRingId := flags.FlagToStringValue(p, cmd, keyRingIdFlag) - keyId := flags.FlagToStringValue(p, cmd, keyIdFlag) - - // Validate the uuid format of the IDs - errKeyRing := utils.ValidateUUID(keyRingId) - errKey := utils.ValidateUUID(keyId) - if errKeyRing != nil || errKey != nil { - return nil, &errors.DSAInputPlanError{ - Cmd: cmd, - } - } - model := inputModel{ GlobalFlagModel: globalFlags, - KeyRingId: keyRingId, - KeyId: keyId, + KeyRingId: flags.FlagToStringValue(p, cmd, keyRingIdFlag), + KeyId: flags.FlagToStringValue(p, cmd, keyIdFlag), } if p.IsVerbosityDebug() { @@ -127,8 +115,8 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClie } func configureFlags(cmd *cobra.Command) { - cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS Key Ring where the Key is stored") - cmd.Flags().Var(flags.UUIDFlag(), keyIdFlag, "ID of the actual Key") + cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS key Ring where the key is stored") + cmd.Flags().Var(flags.UUIDFlag(), keyIdFlag, "ID of the actual key") err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, keyIdFlag) cobra.CheckErr(err) } @@ -142,7 +130,7 @@ func outputResult(p *print.Printer, outputFormat string, resp *kms.Version) erro case print.JSONOutputFormat: details, err := json.MarshalIndent(resp, "", " ") if err != nil { - return fmt.Errorf("marshal KMS Key Version: %w", err) + return fmt.Errorf("marshal KMS key version: %w", err) } p.Outputln(string(details)) return nil @@ -150,13 +138,13 @@ func outputResult(p *print.Printer, outputFormat string, resp *kms.Version) erro case print.YAMLOutputFormat: details, err := yaml.MarshalWithOptions(resp, yaml.IndentSequence(true), yaml.UseJSONMarshaler()) if err != nil { - return fmt.Errorf("marshal KMS Key Version: %w", err) + return fmt.Errorf("marshal KMS key version: %w", err) } p.Outputln(string(details)) return nil default: - p.Outputf("Rotated Key %s\n", utils.PtrString(resp.KeyId)) + p.Outputf("Rotated key %s\n", utils.PtrString(resp.KeyId)) return nil } } From 77c6d96a94ecb7250a01581b67abcc3909754858 Mon Sep 17 00:00:00 2001 From: Jan Sternagel Date: Thu, 11 Sep 2025 14:50:01 +0200 Subject: [PATCH 19/52] nil pointer safe --- .../cmd/beta/kms/keyring/create/create.go | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/internal/cmd/beta/kms/keyring/create/create.go b/internal/cmd/beta/kms/keyring/create/create.go index c12bcb423..df3e9f756 100644 --- a/internal/cmd/beta/kms/keyring/create/create.go +++ b/internal/cmd/beta/kms/keyring/create/create.go @@ -37,15 +37,15 @@ type inputModel struct { func NewCmd(params *params.CmdParams) *cobra.Command { cmd := &cobra.Command{ Use: "create", - Short: "Creates a KMS Key Ring", - Long: "Creates a KMS Key Ring.", + Short: "Creates a KMS key ring", + Long: "Creates a KMS key ring.", Args: args.NoArgs, Example: examples.Build( examples.NewExample( `Create a KMS key ring`, "$ stakit beta kms keyring create --name my-keyring"), examples.NewExample( - `Create a KMS Key ring with a description`, + `Create a KMS key ring with a description`, "$ stakit beta kms keyring create --name my-keyring --description my-description"), ), RunE: func(cmd *cobra.Command, _ []string) error { @@ -68,7 +68,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { } if !model.AssumeYes { - prompt := fmt.Sprintf("Are you sure you want to create a KMS Key Ring for project %q?", projectLabel) + prompt := fmt.Sprintf("Are you sure you want to create a KMS key ring for project %q?", projectLabel) err = params.Printer.PromptForConfirmation(prompt) if err != nil { return err @@ -80,8 +80,14 @@ func NewCmd(params *params.CmdParams) *cobra.Command { keyRing, err := req.Execute() if err != nil { - return fmt.Errorf("create KMS Key Ring: %w", err) + return fmt.Errorf("create KMS key ring: %w", err) } + + // Prevent potential nil pointer dereference + if keyRing == nil || keyRing.Id == nil { + return fmt.Errorf("API call succeeded but returned an invalid response (missing key ring ID)") + } + keyRingId := *keyRing.Id // Wait for async operation, if async mode not enabled @@ -90,7 +96,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { s.Start("Creating instance") _, err = wait.CreateKeyRingWaitHandler(ctx, apiClient, model.ProjectId, model.Region, keyRingId).WaitWithContext(ctx) if err != nil { - return fmt.Errorf("wait for KMS Key Ring creation: %w", err) + return fmt.Errorf("wait for KMS key ring creation: %w", err) } s.Stop() } @@ -159,7 +165,7 @@ func outputResult(p *print.Printer, outputFormat, projectLabel string, resp *kms case print.JSONOutputFormat: details, err := json.MarshalIndent(resp, "", " ") if err != nil { - return fmt.Errorf("marshal KMS Keyring: %w", err) + return fmt.Errorf("marshal KMS key ring: %w", err) } p.Outputln(string(details)) return nil @@ -167,7 +173,7 @@ func outputResult(p *print.Printer, outputFormat, projectLabel string, resp *kms case print.YAMLOutputFormat: details, err := yaml.MarshalWithOptions(resp, yaml.IndentSequence(true), yaml.UseJSONMarshaler()) if err != nil { - return fmt.Errorf("marshal KMS Keyring: %w", err) + return fmt.Errorf("marshal KMS key ring: %w", err) } p.Outputln(string(details)) return nil @@ -179,8 +185,8 @@ func outputResult(p *print.Printer, outputFormat, projectLabel string, resp *kms } func configureFlags(cmd *cobra.Command) { - cmd.Flags().String(keyRingNameFlag, "", "Name of the KMS Key Ring") - cmd.Flags().String(descriptionFlag, "", "Optinal description of the Key Ring") + cmd.Flags().String(keyRingNameFlag, "", "Name of the KMS key ring") + cmd.Flags().String(descriptionFlag, "", "Optional description of the key ring") err := flags.MarkFlagsRequired(cmd, keyRingNameFlag) cobra.CheckErr(err) From f10d6c1b8a2c2c7cd06563371e881d1633061ddf Mon Sep 17 00:00:00 2001 From: Jan Sternagel Date: Thu, 11 Sep 2025 14:55:08 +0200 Subject: [PATCH 20/52] json/yaml output type safe --- internal/cmd/beta/kms/key/restore/restore.go | 70 ++++++++++++------ .../cmd/beta/kms/key/restore/restore_test.go | 43 +++++++++++ .../cmd/beta/kms/keyring/delete/delete.go | 53 ++++++++++++-- .../beta/kms/keyring/delete/delete_test.go | 38 ++++++++++ .../cmd/beta/kms/version/destroy/destroy.go | 61 ++++++++++++++-- .../beta/kms/version/destroy/destroy_test.go | 47 ++++++++++++ .../cmd/beta/kms/version/disable/disable.go | 63 +++++++++++++--- .../beta/kms/version/disable/disable_test.go | 47 ++++++++++++ .../cmd/beta/kms/version/enable/enable.go | 63 +++++++++++++--- .../beta/kms/version/enable/enable_test.go | 47 ++++++++++++ .../cmd/beta/kms/version/restore/restore.go | 61 ++++++++++++++-- .../beta/kms/version/restore/restore_test.go | 47 ++++++++++++ .../cmd/beta/kms/wrappingkey/delete/delete.go | 72 +++++++++++++------ .../kms/wrappingkey/delete/delete_test.go | 39 ++++++++++ 14 files changed, 671 insertions(+), 80 deletions(-) diff --git a/internal/cmd/beta/kms/key/restore/restore.go b/internal/cmd/beta/kms/key/restore/restore.go index 1abcc22f1..1b9622769 100644 --- a/internal/cmd/beta/kms/key/restore/restore.go +++ b/internal/cmd/beta/kms/key/restore/restore.go @@ -2,6 +2,7 @@ package restore import ( "context" + "encoding/json" "fmt" "github.com/spf13/cobra" @@ -13,9 +14,9 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/print" kmsUtils "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/utils" + "gopkg.in/yaml.v2" "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/client" - "github.com/stackitcloud/stackit-cli/internal/pkg/utils" "github.com/stackitcloud/stackit-sdk-go/services/kms" ) @@ -33,12 +34,12 @@ type inputModel struct { func NewCmd(params *params.CmdParams) *cobra.Command { cmd := &cobra.Command{ Use: "restore", - Short: "Resotre a Key", + Short: "Resotre a key", Long: "Restores the given key from being deleted.", Args: args.NoArgs, Example: examples.Build( examples.NewExample( - `Restore a KMS Key "my-key-id" inside the Key Ring "my-key-ring-id" that was scheduled for deletion.`, + `Restore a KMS key "my-key-id" inside the key ring "my-key-ring-id" that was scheduled for deletion.`, `$ stackit beta kms keyring restore --key-ring "my-key-ring-id" --key "my-key-id"`), ), RunE: func(cmd *cobra.Command, _ []string) error { @@ -72,11 +73,10 @@ func NewCmd(params *params.CmdParams) *cobra.Command { req := buildRequest(ctx, model, apiClient) err = req.Execute() if err != nil { - return fmt.Errorf("restore KMS Key: %w", err) + return fmt.Errorf("restore KMS key: %w", err) } - params.Printer.Info("Restored Key %q\n", keyName) - return nil + return outputResult(params.Printer, model.OutputFormat, model.KeyId, keyName) }, } @@ -90,22 +90,10 @@ func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { return nil, &errors.ProjectIdError{} } - keyRingId := flags.FlagToStringValue(p, cmd, keyRingIdFlag) - keyId := flags.FlagToStringValue(p, cmd, keyIdFlag) - - // Validate the uuid format of the IDs - errKeyRing := utils.ValidateUUID(keyRingId) - errKey := utils.ValidateUUID(keyId) - if errKeyRing != nil || errKey != nil { - return nil, &errors.DSAInputPlanError{ - Cmd: cmd, - } - } - model := inputModel{ GlobalFlagModel: globalFlags, - KeyRingId: keyRingId, - KeyId: keyId, + KeyRingId: flags.FlagToStringValue(p, cmd, keyRingIdFlag), + KeyId: flags.FlagToStringValue(p, cmd, keyIdFlag), } if p.IsVerbosityDebug() { @@ -131,3 +119,45 @@ func configureFlags(cmd *cobra.Command) { err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, keyIdFlag) cobra.CheckErr(err) } + +func outputResult(p *print.Printer, outputFormat, keyId, keyName string) error { + switch outputFormat { + case print.JSONOutputFormat: + details := struct { + KeyId string `json:"keyId"` + KeyName string `json:"keyName"` + Status string `json:"status"` + }{ + KeyId: keyId, + KeyName: keyName, + Status: "key restored", + } + b, err := json.MarshalIndent(details, "", " ") + if err != nil { + return fmt.Errorf("marshal output to JSON: %w", err) + } + p.Outputln(string(b)) + return nil + + case print.YAMLOutputFormat: + details := struct { + KeyId string `yaml:"keyId"` + KeyName string `yaml:"keyName"` + Status string `yaml:"status"` + }{ + KeyId: keyId, + KeyName: keyName, + Status: "key restored", + } + b, err := yaml.Marshal(details) + if err != nil { + return fmt.Errorf("marshal output to YAML: %w", err) + } + p.Outputln(string(b)) + return nil + + default: + p.Outputf("Successfully restored KMS key %q\n", keyName) + return nil + } +} diff --git a/internal/cmd/beta/kms/key/restore/restore_test.go b/internal/cmd/beta/kms/key/restore/restore_test.go index 52a375f54..ef654faf6 100644 --- a/internal/cmd/beta/kms/key/restore/restore_test.go +++ b/internal/cmd/beta/kms/key/restore/restore_test.go @@ -8,6 +8,7 @@ import ( "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/uuid" "github.com/spf13/cobra" + "github.com/stackitcloud/stackit-cli/internal/cmd/params" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/print" "github.com/stackitcloud/stackit-sdk-go/services/kms" @@ -225,3 +226,45 @@ func TestBuildRequest(t *testing.T) { }) } } + +func TestOutputResult(t *testing.T) { + tests := []struct { + description string + wantErr bool + outputFormat string + keyId string + keyName string + }{ + { + description: "default output", + keyId: uuid.NewString(), + keyName: uuid.NewString(), + wantErr: false, + }, + { + description: "json output", + outputFormat: print.JSONOutputFormat, + keyId: uuid.NewString(), + keyName: uuid.NewString(), + wantErr: false, + }, + { + description: "yaml output", + outputFormat: print.YAMLOutputFormat, + keyId: uuid.NewString(), + keyName: uuid.NewString(), + wantErr: false, + }, + } + + p := print.NewPrinter() + p.Cmd = NewCmd(¶ms.CmdParams{Printer: p}) + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + err := outputResult(p, tt.outputFormat, tt.keyId, tt.keyName) + if (err != nil) != tt.wantErr { + t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/internal/cmd/beta/kms/keyring/delete/delete.go b/internal/cmd/beta/kms/keyring/delete/delete.go index 55049d083..34f542221 100644 --- a/internal/cmd/beta/kms/keyring/delete/delete.go +++ b/internal/cmd/beta/kms/keyring/delete/delete.go @@ -2,8 +2,10 @@ package delete import ( "context" + "encoding/json" "fmt" + "github.com/goccy/go-yaml" "github.com/spf13/cobra" "github.com/stackitcloud/stackit-cli/internal/cmd/params" "github.com/stackitcloud/stackit-cli/internal/pkg/args" @@ -30,12 +32,12 @@ type inputModel struct { func NewCmd(params *params.CmdParams) *cobra.Command { cmd := &cobra.Command{ Use: fmt.Sprintf("delete %s", keyRingIdArg), - Short: "Deletes a KMS Keyring", - Long: "Deletes a KMS Keyring.", + Short: "Deletes a KMS key ring", + Long: "Deletes a KMS key ring.", Args: args.SingleArg(keyRingIdArg, utils.ValidateUUID), Example: examples.Build( examples.NewExample( - `Delete a KMS Keyring with ID "xxx"`, + `Delete a KMS key ring with ID "xxx"`, "$ stackit beta kms keyring delete xxx"), ), RunE: func(cmd *cobra.Command, args []string) error { @@ -69,13 +71,12 @@ func NewCmd(params *params.CmdParams) *cobra.Command { req := buildRequest(ctx, model, apiClient) err = req.Execute() if err != nil { - return fmt.Errorf("delete KMS Key Ring: %w", err) + return fmt.Errorf("delete KMS key ring: %w", err) } - // Wait for async operation not relevant. Keyring deletion is synchronous. + // Wait for async operation not relevant. Key ring deletion is synchronous. - params.Printer.Info("Deleted key ring %q\n", keyRingLabel) - return nil + return outputResult(params.Printer, model.OutputFormat, keyRingLabel) }, } return cmd @@ -110,3 +111,41 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClie req := apiClient.DeleteKeyRing(ctx, model.ProjectId, model.Region, model.KeyRingId) return req } + +func outputResult(p *print.Printer, outputFormat, keyRingLabel string) error { + switch outputFormat { + case print.JSONOutputFormat: + details := struct { + KeyRingLabel string `json:"keyRingLabel"` + Status string `json:"status"` + }{ + KeyRingLabel: keyRingLabel, + Status: "Key ring deleted.", + } + b, err := json.MarshalIndent(details, "", " ") + if err != nil { + return fmt.Errorf("marshal output to JSON: %w", err) + } + p.Outputln(string(b)) + return nil + + case print.YAMLOutputFormat: + details := struct { + KeyRingLabel string `yaml:"keyRingLabel"` + Status string `yaml:"status"` + }{ + KeyRingLabel: keyRingLabel, + Status: "Key ring deleted.", + } + b, err := yaml.Marshal(details) + if err != nil { + return fmt.Errorf("marshal output to YAML: %w", err) + } + p.Outputln(string(b)) + return nil + + default: + p.Outputf("Deleted key ring: %s\n", keyRingLabel) + return nil + } +} diff --git a/internal/cmd/beta/kms/keyring/delete/delete_test.go b/internal/cmd/beta/kms/keyring/delete/delete_test.go index c53e7d7f0..c3b400ea9 100644 --- a/internal/cmd/beta/kms/keyring/delete/delete_test.go +++ b/internal/cmd/beta/kms/keyring/delete/delete_test.go @@ -210,3 +210,41 @@ func TestBuildRequest(t *testing.T) { }) } } + +func TestOutputResult(t *testing.T) { + tests := []struct { + description string + wantErr bool + outputFormat string + keyRingLabel string + }{ + { + description: "default output", + keyRingLabel: "yourKeyRing", + wantErr: false, + }, + { + description: "json output", + outputFormat: print.JSONOutputFormat, + keyRingLabel: "yourKeyRing", + wantErr: false, + }, + { + description: "yaml output", + outputFormat: print.YAMLOutputFormat, + keyRingLabel: "yourKeyRing", + wantErr: false, + }, + } + + p := print.NewPrinter() + p.Cmd = NewCmd(¶ms.CmdParams{Printer: p}) + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + err := outputResult(p, tt.outputFormat, tt.keyRingLabel) + if (err != nil) != tt.wantErr { + t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/internal/cmd/beta/kms/version/destroy/destroy.go b/internal/cmd/beta/kms/version/destroy/destroy.go index 42811b276..e20d11df7 100644 --- a/internal/cmd/beta/kms/version/destroy/destroy.go +++ b/internal/cmd/beta/kms/version/destroy/destroy.go @@ -2,6 +2,7 @@ package destroy import ( "context" + "encoding/json" "fmt" "github.com/spf13/cobra" @@ -15,6 +16,7 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/client" kmsUtils "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/utils" "github.com/stackitcloud/stackit-sdk-go/services/kms" + "gopkg.in/yaml.v2" ) const ( @@ -33,7 +35,7 @@ type inputModel struct { func NewCmd(params *params.CmdParams) *cobra.Command { cmd := &cobra.Command{ Use: "destroy", - Short: "Destroy a Key Versions", + Short: "Destroy a key version", Long: "Removes the key material of a version.", Args: args.NoArgs, Example: examples.Build( @@ -59,17 +61,16 @@ func NewCmd(params *params.CmdParams) *cobra.Command { params.Printer.Debug(print.ErrorLevel, "get key name: %v", err) keyName = model.KeyId } - // This operatio can be undone. Don't ask for confirmation! + // This operation can be undone. Don't ask for confirmation! // Call API req := buildRequest(ctx, model, apiClient) err = req.Execute() if err != nil { - return fmt.Errorf("destroy Key Version: %w", err) + return fmt.Errorf("destroy key Version: %w", err) } - params.Printer.Info("Destroyed version %d of Key %q\n", *model.VersionNumber, keyName) - return nil + return outputResult(params.Printer, model.OutputFormat, *model.VersionNumber, model.KeyId, keyName) }, } @@ -107,10 +108,56 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClie } func configureFlags(cmd *cobra.Command) { - cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS Key Ring") - cmd.Flags().Var(flags.UUIDFlag(), keyIdFlag, "ID of the Key") + cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS key ring") + cmd.Flags().Var(flags.UUIDFlag(), keyIdFlag, "ID of the key") cmd.Flags().Int64(versionNumberFlag, 0, "Version number of the key") err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, keyIdFlag, versionNumberFlag) cobra.CheckErr(err) } + +func outputResult(p *print.Printer, outputFormat string, versionNumber int64, keyId, keyName string) error { + switch outputFormat { + case print.JSONOutputFormat: + details := struct { + KeyId string `json:"keyId"` + KeyName string `json:"keyName"` + VersionNumber int64 `json:"versionNumber"` + Status string `json:"status"` + }{ + KeyId: keyId, + KeyName: keyName, + VersionNumber: versionNumber, + Status: fmt.Sprintf("Destroyed version %d of key '%s'.", versionNumber, keyName), + } + b, err := json.MarshalIndent(details, "", " ") + if err != nil { + return fmt.Errorf("marshal output to JSON: %w", err) + } + p.Outputln(string(b)) + return nil + + case print.YAMLOutputFormat: + details := struct { + KeyId string `yaml:"keyId"` + KeyName string `yaml:"keyName"` + VersionNumber int64 `yaml:"versionNumber"` + Status string `yaml:"status"` + }{ + KeyId: keyId, + KeyName: keyName, + VersionNumber: versionNumber, + Status: fmt.Sprintf("Destroyed version %d of key '%s'.", versionNumber, keyName), + } + b, err := yaml.Marshal(details) + if err != nil { + return fmt.Errorf("marshal output to YAML: %w", err) + } + p.Outputln(string(b)) + return nil + + default: + p.Outputf("Destroyed version %d of key '%q'\n", versionNumber, keyName) + return nil + } +} diff --git a/internal/cmd/beta/kms/version/destroy/destroy_test.go b/internal/cmd/beta/kms/version/destroy/destroy_test.go index 6e1887714..407a87d8d 100644 --- a/internal/cmd/beta/kms/version/destroy/destroy_test.go +++ b/internal/cmd/beta/kms/version/destroy/destroy_test.go @@ -8,6 +8,7 @@ import ( "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/uuid" "github.com/spf13/cobra" + "github.com/stackitcloud/stackit-cli/internal/cmd/params" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/print" "github.com/stackitcloud/stackit-cli/internal/pkg/utils" @@ -250,3 +251,49 @@ func TestBuildRequest(t *testing.T) { }) } } + +func TestOutputResult(t *testing.T) { + tests := []struct { + description string + wantErr bool + outputFormat string + versionNumber int64 + keyId string + keyName string + }{ + { + description: "default output", + versionNumber: 1, + keyId: uuid.NewString(), + keyName: "your-key", + wantErr: false, + }, + { + description: "json output", + outputFormat: print.JSONOutputFormat, + versionNumber: 1, + keyId: uuid.NewString(), + keyName: "your-key", + wantErr: false, + }, + { + description: "yaml output", + outputFormat: print.YAMLOutputFormat, + versionNumber: 1, + keyId: uuid.NewString(), + keyName: "your-key", + wantErr: false, + }, + } + + p := print.NewPrinter() + p.Cmd = NewCmd(¶ms.CmdParams{Printer: p}) + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + err := outputResult(p, tt.outputFormat, tt.versionNumber, tt.keyId, tt.keyName) + if (err != nil) != tt.wantErr { + t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/internal/cmd/beta/kms/version/disable/disable.go b/internal/cmd/beta/kms/version/disable/disable.go index 6eee81fa3..1234cfd22 100644 --- a/internal/cmd/beta/kms/version/disable/disable.go +++ b/internal/cmd/beta/kms/version/disable/disable.go @@ -2,6 +2,7 @@ package disable import ( "context" + "encoding/json" "fmt" "github.com/spf13/cobra" @@ -17,6 +18,7 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/spinner" "github.com/stackitcloud/stackit-sdk-go/services/kms" "github.com/stackitcloud/stackit-sdk-go/services/kms/wait" + "gopkg.in/yaml.v2" ) const ( @@ -35,7 +37,7 @@ type inputModel struct { func NewCmd(params *params.CmdParams) *cobra.Command { cmd := &cobra.Command{ Use: "disable", - Short: "Disable a Key Versions", + Short: "Disable a key version", Long: "Disable the given key version.", Args: args.NoArgs, Example: examples.Build( @@ -62,13 +64,13 @@ func NewCmd(params *params.CmdParams) *cobra.Command { keyName = model.KeyId } - // This operatio can be undone. Don't ask for confirmation! + // This operation can be undone. Don't ask for confirmation! // Call API req := buildRequest(ctx, model, apiClient) err = req.Execute() if err != nil { - return fmt.Errorf("disable Key Version: %w", err) + return fmt.Errorf("disable key version: %w", err) } // Wait for async operation, if async mode not enabled @@ -77,13 +79,12 @@ func NewCmd(params *params.CmdParams) *cobra.Command { s.Start("Disableing key version") _, err = wait.DisableKeyVersionWaitHandler(ctx, apiClient, model.ProjectId, model.Region, model.KeyRingId, model.KeyId, *model.VersionNumber).WaitWithContext(ctx) if err != nil { - return fmt.Errorf("wait for Key Version to be disabled: %w", err) + return fmt.Errorf("wait for key version to be disabled: %w", err) } s.Stop() } - params.Printer.Info("Disabled version %d of Key %q\n", *model.VersionNumber, keyName) - return nil + return outputResult(params.Printer, model.OutputFormat, *model.VersionNumber, model.KeyId, keyName) }, } @@ -121,10 +122,56 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClie } func configureFlags(cmd *cobra.Command) { - cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS Key Ring") - cmd.Flags().Var(flags.UUIDFlag(), keyIdFlag, "ID of the Key") + cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS key ring") + cmd.Flags().Var(flags.UUIDFlag(), keyIdFlag, "ID of the rey") cmd.Flags().Int64(versionNumberFlag, 0, "Version number of the key") err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, keyIdFlag, versionNumberFlag) cobra.CheckErr(err) } + +func outputResult(p *print.Printer, outputFormat string, versionNumber int64, keyId, keyName string) error { + switch outputFormat { + case print.JSONOutputFormat: + details := struct { + KeyId string `json:"keyId"` + KeyName string `json:"keyName"` + VersionNumber int64 `json:"versionNumber"` + Status string `json:"status"` + }{ + KeyId: keyId, + KeyName: keyName, + VersionNumber: versionNumber, + Status: fmt.Sprintf("Disabled version %d of key '%s'.", versionNumber, keyName), + } + b, err := json.MarshalIndent(details, "", " ") + if err != nil { + return fmt.Errorf("marshal output to JSON: %w", err) + } + p.Outputln(string(b)) + return nil + + case print.YAMLOutputFormat: + details := struct { + KeyId string `yaml:"keyId"` + KeyName string `yaml:"keyName"` + VersionNumber int64 `yaml:"versionNumber"` + Status string `yaml:"status"` + }{ + KeyId: keyId, + KeyName: keyName, + VersionNumber: versionNumber, + Status: fmt.Sprintf("Disabled version %d of key '%s'.", versionNumber, keyName), + } + b, err := yaml.Marshal(details) + if err != nil { + return fmt.Errorf("marshal output to YAML: %w", err) + } + p.Outputln(string(b)) + return nil + + default: + p.Outputf("Disabled version %d of key '%q'\n", versionNumber, keyName) + return nil + } +} diff --git a/internal/cmd/beta/kms/version/disable/disable_test.go b/internal/cmd/beta/kms/version/disable/disable_test.go index b134c5029..22784abe9 100644 --- a/internal/cmd/beta/kms/version/disable/disable_test.go +++ b/internal/cmd/beta/kms/version/disable/disable_test.go @@ -8,6 +8,7 @@ import ( "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/uuid" "github.com/spf13/cobra" + "github.com/stackitcloud/stackit-cli/internal/cmd/params" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/print" "github.com/stackitcloud/stackit-cli/internal/pkg/utils" @@ -250,3 +251,49 @@ func TestBuildRequest(t *testing.T) { }) } } + +func TestOutputResult(t *testing.T) { + tests := []struct { + description string + wantErr bool + outputFormat string + versionNumber int64 + keyId string + keyName string + }{ + { + description: "default output", + versionNumber: 1, + keyId: uuid.NewString(), + keyName: "your-key", + wantErr: false, + }, + { + description: "json output", + outputFormat: print.JSONOutputFormat, + versionNumber: 1, + keyId: uuid.NewString(), + keyName: "your-key", + wantErr: false, + }, + { + description: "yaml output", + outputFormat: print.YAMLOutputFormat, + versionNumber: 1, + keyId: uuid.NewString(), + keyName: "your-key", + wantErr: false, + }, + } + + p := print.NewPrinter() + p.Cmd = NewCmd(¶ms.CmdParams{Printer: p}) + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + err := outputResult(p, tt.outputFormat, tt.versionNumber, tt.keyId, tt.keyName) + if (err != nil) != tt.wantErr { + t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/internal/cmd/beta/kms/version/enable/enable.go b/internal/cmd/beta/kms/version/enable/enable.go index 4aa52bac7..7b5d99dce 100644 --- a/internal/cmd/beta/kms/version/enable/enable.go +++ b/internal/cmd/beta/kms/version/enable/enable.go @@ -2,6 +2,7 @@ package enable import ( "context" + "encoding/json" "fmt" "github.com/spf13/cobra" @@ -17,6 +18,7 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/spinner" "github.com/stackitcloud/stackit-sdk-go/services/kms" "github.com/stackitcloud/stackit-sdk-go/services/kms/wait" + "gopkg.in/yaml.v2" ) const ( @@ -35,7 +37,7 @@ type inputModel struct { func NewCmd(params *params.CmdParams) *cobra.Command { cmd := &cobra.Command{ Use: "enable", - Short: "Enable a Key Versions", + Short: "Enable a key version", Long: "Enable the given key version.", Args: args.NoArgs, Example: examples.Build( @@ -62,13 +64,13 @@ func NewCmd(params *params.CmdParams) *cobra.Command { keyName = model.KeyId } - // This operatio can be undone. Don't ask for confirmation! + // This operation can be undone. Don't ask for confirmation! // Call API req := buildRequest(ctx, model, apiClient) err = req.Execute() if err != nil { - return fmt.Errorf("enable Key Version: %w", err) + return fmt.Errorf("enable key version: %w", err) } // Wait for async operation, if async mode not enabled @@ -77,13 +79,12 @@ func NewCmd(params *params.CmdParams) *cobra.Command { s.Start("Enabling key version") _, err = wait.EnableKeyVersionWaitHandler(ctx, apiClient, model.ProjectId, model.Region, model.KeyRingId, model.KeyId, *model.VersionNumber).WaitWithContext(ctx) if err != nil { - return fmt.Errorf("wait for Key Version to be enabled: %w", err) + return fmt.Errorf("wait for key version to be enabled: %w", err) } s.Stop() } - params.Printer.Info("Enabled version %d of Key %q\n", *model.VersionNumber, keyName) - return nil + return outputResult(params.Printer, model.OutputFormat, *model.VersionNumber, model.KeyId, keyName) }, } @@ -121,10 +122,56 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClie } func configureFlags(cmd *cobra.Command) { - cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS Key Ring") - cmd.Flags().Var(flags.UUIDFlag(), keyIdFlag, "ID of the Key") + cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS key ring") + cmd.Flags().Var(flags.UUIDFlag(), keyIdFlag, "ID of the key") cmd.Flags().Int64(versionNumberFlag, 0, "Version number of the key") err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, keyIdFlag, versionNumberFlag) cobra.CheckErr(err) } + +func outputResult(p *print.Printer, outputFormat string, versionNumber int64, keyId, keyName string) error { + switch outputFormat { + case print.JSONOutputFormat: + details := struct { + KeyId string `json:"keyId"` + KeyName string `json:"keyName"` + VersionNumber int64 `json:"versionNumber"` + Status string `json:"status"` + }{ + KeyId: keyId, + KeyName: keyName, + VersionNumber: versionNumber, + Status: fmt.Sprintf("Enabled version %d of key '%s'.", versionNumber, keyName), + } + b, err := json.MarshalIndent(details, "", " ") + if err != nil { + return fmt.Errorf("marshal output to JSON: %w", err) + } + p.Outputln(string(b)) + return nil + + case print.YAMLOutputFormat: + details := struct { + KeyId string `yaml:"keyId"` + KeyName string `yaml:"keyName"` + VersionNumber int64 `yaml:"versionNumber"` + Status string `yaml:"status"` + }{ + KeyId: keyId, + KeyName: keyName, + VersionNumber: versionNumber, + Status: fmt.Sprintf("Enabled version %d of key '%s'.", versionNumber, keyName), + } + b, err := yaml.Marshal(details) + if err != nil { + return fmt.Errorf("marshal output to YAML: %w", err) + } + p.Outputln(string(b)) + return nil + + default: + p.Outputf("Enabled version %d of key '%q'\n", versionNumber, keyName) + return nil + } +} diff --git a/internal/cmd/beta/kms/version/enable/enable_test.go b/internal/cmd/beta/kms/version/enable/enable_test.go index ed95e783e..2e09a5d6d 100644 --- a/internal/cmd/beta/kms/version/enable/enable_test.go +++ b/internal/cmd/beta/kms/version/enable/enable_test.go @@ -8,6 +8,7 @@ import ( "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/uuid" "github.com/spf13/cobra" + "github.com/stackitcloud/stackit-cli/internal/cmd/params" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/print" "github.com/stackitcloud/stackit-cli/internal/pkg/utils" @@ -250,3 +251,49 @@ func TestBuildRequest(t *testing.T) { }) } } + +func TestOutputResult(t *testing.T) { + tests := []struct { + description string + wantErr bool + outputFormat string + versionNumber int64 + keyId string + keyName string + }{ + { + description: "default output", + versionNumber: 1, + keyId: uuid.NewString(), + keyName: "your-key", + wantErr: false, + }, + { + description: "json output", + outputFormat: print.JSONOutputFormat, + versionNumber: 1, + keyId: uuid.NewString(), + keyName: "your-key", + wantErr: false, + }, + { + description: "yaml output", + outputFormat: print.YAMLOutputFormat, + versionNumber: 1, + keyId: uuid.NewString(), + keyName: "your-key", + wantErr: false, + }, + } + + p := print.NewPrinter() + p.Cmd = NewCmd(¶ms.CmdParams{Printer: p}) + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + err := outputResult(p, tt.outputFormat, tt.versionNumber, tt.keyId, tt.keyName) + if (err != nil) != tt.wantErr { + t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/internal/cmd/beta/kms/version/restore/restore.go b/internal/cmd/beta/kms/version/restore/restore.go index c595879d0..43dae80df 100644 --- a/internal/cmd/beta/kms/version/restore/restore.go +++ b/internal/cmd/beta/kms/version/restore/restore.go @@ -2,6 +2,7 @@ package restore import ( "context" + "encoding/json" "fmt" "github.com/spf13/cobra" @@ -15,6 +16,7 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/client" kmsUtils "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/utils" "github.com/stackitcloud/stackit-sdk-go/services/kms" + "gopkg.in/yaml.v2" ) const ( @@ -33,7 +35,7 @@ type inputModel struct { func NewCmd(params *params.CmdParams) *cobra.Command { cmd := &cobra.Command{ Use: "restore", - Short: "Restore a Key Versions", + Short: "Restore a key version", Long: "Restores the specified version of key.", Args: args.NoArgs, Example: examples.Build( @@ -60,17 +62,16 @@ func NewCmd(params *params.CmdParams) *cobra.Command { keyName = model.KeyId } - // This operatio can be undone. Don't ask for confirmation! + // This operation can be undone. Don't ask for confirmation! // Call API req := buildRequest(ctx, model, apiClient) err = req.Execute() if err != nil { - return fmt.Errorf("restore Key Version: %w", err) + return fmt.Errorf("restore key Version: %w", err) } - params.Printer.Outputf("Restored version %d of Key %q\n", *model.VersionNumber, keyName) - return nil + return outputResult(params.Printer, model.OutputFormat, *model.VersionNumber, model.KeyId, keyName) }, } @@ -108,10 +109,56 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClie } func configureFlags(cmd *cobra.Command) { - cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS Key Ring") - cmd.Flags().Var(flags.UUIDFlag(), keyIdFlag, "ID of the Key") + cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS key ring") + cmd.Flags().Var(flags.UUIDFlag(), keyIdFlag, "ID of the key") cmd.Flags().Int64(versionNumberFlag, 0, "Version number of the key") err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, keyIdFlag, versionNumberFlag) cobra.CheckErr(err) } + +func outputResult(p *print.Printer, outputFormat string, versionNumber int64, keyId, keyName string) error { + switch outputFormat { + case print.JSONOutputFormat: + details := struct { + KeyId string `json:"keyId"` + KeyName string `json:"keyName"` + VersionNumber int64 `json:"versionNumber"` + Status string `json:"status"` + }{ + KeyId: keyId, + KeyName: keyName, + VersionNumber: versionNumber, + Status: fmt.Sprintf("Restored version %d of key '%s'.", versionNumber, keyName), + } + b, err := json.MarshalIndent(details, "", " ") + if err != nil { + return fmt.Errorf("marshal output to JSON: %w", err) + } + p.Outputln(string(b)) + return nil + + case print.YAMLOutputFormat: + details := struct { + KeyId string `yaml:"keyId"` + KeyName string `yaml:"keyName"` + VersionNumber int64 `yaml:"versionNumber"` + Status string `yaml:"status"` + }{ + KeyId: keyId, + KeyName: keyName, + VersionNumber: versionNumber, + Status: fmt.Sprintf("Restored version %d of key '%s'.", versionNumber, keyName), + } + b, err := yaml.Marshal(details) + if err != nil { + return fmt.Errorf("marshal output to YAML: %w", err) + } + p.Outputln(string(b)) + return nil + + default: + p.Outputf("Restored version %d of key '%q'\n", versionNumber, keyName) + return nil + } +} diff --git a/internal/cmd/beta/kms/version/restore/restore_test.go b/internal/cmd/beta/kms/version/restore/restore_test.go index 3fa62cbc9..dc4e6799b 100644 --- a/internal/cmd/beta/kms/version/restore/restore_test.go +++ b/internal/cmd/beta/kms/version/restore/restore_test.go @@ -8,6 +8,7 @@ import ( "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/uuid" "github.com/spf13/cobra" + "github.com/stackitcloud/stackit-cli/internal/cmd/params" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/print" "github.com/stackitcloud/stackit-cli/internal/pkg/utils" @@ -250,3 +251,49 @@ func TestBuildRequest(t *testing.T) { }) } } + +func TestOutputResult(t *testing.T) { + tests := []struct { + description string + wantErr bool + outputFormat string + versionNumber int64 + keyId string + keyName string + }{ + { + description: "default output", + versionNumber: 1, + keyId: uuid.NewString(), + keyName: "your-key", + wantErr: false, + }, + { + description: "json output", + outputFormat: print.JSONOutputFormat, + versionNumber: 1, + keyId: uuid.NewString(), + keyName: "your-key", + wantErr: false, + }, + { + description: "yaml output", + outputFormat: print.YAMLOutputFormat, + versionNumber: 1, + keyId: uuid.NewString(), + keyName: "your-key", + wantErr: false, + }, + } + + p := print.NewPrinter() + p.Cmd = NewCmd(¶ms.CmdParams{Printer: p}) + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + err := outputResult(p, tt.outputFormat, tt.versionNumber, tt.keyId, tt.keyName) + if (err != nil) != tt.wantErr { + t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/internal/cmd/beta/kms/wrappingkey/delete/delete.go b/internal/cmd/beta/kms/wrappingkey/delete/delete.go index 7b94185cc..d070a38f1 100644 --- a/internal/cmd/beta/kms/wrappingkey/delete/delete.go +++ b/internal/cmd/beta/kms/wrappingkey/delete/delete.go @@ -2,6 +2,7 @@ package delete import ( "context" + "encoding/json" "fmt" "github.com/spf13/cobra" @@ -13,9 +14,9 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/print" kmsUtils "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/utils" + "gopkg.in/yaml.v2" "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/client" - "github.com/stackitcloud/stackit-cli/internal/pkg/utils" "github.com/stackitcloud/stackit-sdk-go/services/kms" ) @@ -33,12 +34,12 @@ type inputModel struct { func NewCmd(params *params.CmdParams) *cobra.Command { cmd := &cobra.Command{ Use: "delete", - Short: "Deletes a KMS Wrapping Key", - Long: "Deletes a KMS Wrapping Key inside a specific Key Ring.", + Short: "Deletes a KMS wrapping key", + Long: "Deletes a KMS wrapping key inside a specific key ring.", Args: args.NoArgs, Example: examples.Build( examples.NewExample( - `Delete a KMS Wrapping Key "my-wrapping-key-id" inside the Key Ring "my-key-ring-id"`, + `Delete a KMS wrapping key "my-wrapping-key-id" inside the key ring "my-key-ring-id"`, `$ stackit beta kms keyring delete --key-ring "my-key-ring-id" --wrapping-key "my-wrapping-key-id"`), ), RunE: func(cmd *cobra.Command, _ []string) error { @@ -72,12 +73,11 @@ func NewCmd(params *params.CmdParams) *cobra.Command { req := buildRequest(ctx, model, apiClient) err = req.Execute() if err != nil { - return fmt.Errorf("delete KMS Wrapping Key: %w", err) + return fmt.Errorf("delete KMS wrapping key: %w", err) } // Wait for async operation not relevant. Wrapping key deletion is synchronous - params.Printer.Info("Deleted wrapping key %q\n", wrappingKeyName) - return nil + return outputResult(params.Printer, model.OutputFormat, wrappingKeyName) }, } @@ -91,22 +91,10 @@ func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { return nil, &errors.ProjectIdError{} } - keyRingId := flags.FlagToStringValue(p, cmd, keyRingIdFlag) - wrappingKeyId := flags.FlagToStringValue(p, cmd, wrappingKeyIdFlag) - - // Validate the uuid format of the IDs - errKeyRing := utils.ValidateUUID(keyRingId) - errWrappingKey := utils.ValidateUUID(wrappingKeyId) - if errKeyRing != nil || errWrappingKey != nil { - return nil, &errors.DSAInputPlanError{ - Cmd: cmd, - } - } - model := inputModel{ GlobalFlagModel: globalFlags, - KeyRingId: keyRingId, - WrappingKey: wrappingKeyId, + KeyRingId: flags.FlagToStringValue(p, cmd, keyRingIdFlag), + WrappingKey: flags.FlagToStringValue(p, cmd, wrappingKeyIdFlag), } if p.IsVerbosityDebug() { @@ -127,8 +115,46 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClie } func configureFlags(cmd *cobra.Command) { - cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS Key Ring where the Wrapping Key is stored") - cmd.Flags().Var(flags.UUIDFlag(), wrappingKeyIdFlag, "ID of the actual Wrapping Key") + cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS key ring where the wrapping key is stored") + cmd.Flags().Var(flags.UUIDFlag(), wrappingKeyIdFlag, "ID of the actual wrapping key") err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, wrappingKeyIdFlag) cobra.CheckErr(err) } + +func outputResult(p *print.Printer, outputFormat, wrappingKeyName string) error { + switch outputFormat { + case print.JSONOutputFormat: + details := struct { + WrappingKeyName string `json:"wrappingKeyName"` + Status string `json:"status"` + }{ + WrappingKeyName: wrappingKeyName, + Status: "Deleted wrapping key.", + } + b, err := json.MarshalIndent(details, "", " ") + if err != nil { + return fmt.Errorf("marshal output to JSON: %w", err) + } + p.Outputln(string(b)) + return nil + + case print.YAMLOutputFormat: + details := struct { + WrappingKeyName string `yaml:"wrappingKeyName"` + Status string `yaml:"status"` + }{ + WrappingKeyName: wrappingKeyName, + Status: "Deleted wrapping key.", + } + b, err := yaml.Marshal(details) + if err != nil { + return fmt.Errorf("marshal output to YAML: %w", err) + } + p.Outputln(string(b)) + return nil + + default: + p.Outputf("Deleted wrapping key: %s\n", wrappingKeyName) + return nil + } +} diff --git a/internal/cmd/beta/kms/wrappingkey/delete/delete_test.go b/internal/cmd/beta/kms/wrappingkey/delete/delete_test.go index 6f6b0ca7f..bef3865f8 100644 --- a/internal/cmd/beta/kms/wrappingkey/delete/delete_test.go +++ b/internal/cmd/beta/kms/wrappingkey/delete/delete_test.go @@ -8,6 +8,7 @@ import ( "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/uuid" "github.com/spf13/cobra" + "github.com/stackitcloud/stackit-cli/internal/cmd/params" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/print" "github.com/stackitcloud/stackit-sdk-go/services/kms" @@ -218,3 +219,41 @@ func TestBuildRequest(t *testing.T) { }) } } + +func TestOutputResult(t *testing.T) { + tests := []struct { + description string + wantErr bool + outputFormat string + wrappingKeyName string + }{ + { + description: "default output", + wrappingKeyName: "yourWrappingKey", + wantErr: false, + }, + { + description: "json output", + outputFormat: print.JSONOutputFormat, + wrappingKeyName: "yourWrappingKey", + wantErr: false, + }, + { + description: "yaml output", + outputFormat: print.YAMLOutputFormat, + wrappingKeyName: "yourWrappingKey", + wantErr: false, + }, + } + + p := print.NewPrinter() + p.Cmd = NewCmd(¶ms.CmdParams{Printer: p}) + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + err := outputResult(p, tt.outputFormat, tt.wrappingKeyName) + if (err != nil) != tt.wantErr { + t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} From c1ba5cc06c22a47f2a1f30244197f33f1ff7cbee Mon Sep 17 00:00:00 2001 From: Jan Sternagel Date: Thu, 11 Sep 2025 14:55:14 +0200 Subject: [PATCH 21/52] updated docs --- docs/stackit_beta_kms.md | 6 ++--- docs/stackit_beta_kms_key.md | 12 +++++----- docs/stackit_beta_kms_key_create.md | 18 +++++++-------- docs/stackit_beta_kms_key_delete.md | 6 ++--- docs/stackit_beta_kms_key_import.md | 10 ++++----- docs/stackit_beta_kms_key_list.md | 8 +++---- docs/stackit_beta_kms_key_restore.md | 4 ++-- docs/stackit_beta_kms_key_rotate.md | 8 +++---- docs/stackit_beta_kms_keyring.md | 10 ++++----- docs/stackit_beta_kms_keyring_create.md | 12 +++++----- docs/stackit_beta_kms_keyring_delete.md | 8 +++---- docs/stackit_beta_kms_keyring_list.md | 10 ++++----- docs/stackit_beta_kms_version.md | 14 ++++++------ docs/stackit_beta_kms_version_destroy.md | 8 +++---- docs/stackit_beta_kms_version_disable.md | 8 +++---- docs/stackit_beta_kms_version_enable.md | 8 +++---- docs/stackit_beta_kms_version_list.md | 10 ++++----- docs/stackit_beta_kms_version_restore.md | 8 +++---- ...ey.md => stackit_beta_kms_wrapping-key.md} | 16 +++++++------- ...> stackit_beta_kms_wrapping-key_create.md} | 22 +++++++++---------- ...> stackit_beta_kms_wrapping-key_delete.md} | 18 +++++++-------- ... => stackit_beta_kms_wrapping-key_list.md} | 8 +++---- 22 files changed, 116 insertions(+), 116 deletions(-) rename docs/{stackit_beta_kms_wrappingkey.md => stackit_beta_kms_wrapping-key.md} (54%) rename docs/{stackit_beta_kms_wrappingkey_create.md => stackit_beta_kms_wrapping-key_create.md} (68%) rename docs/{stackit_beta_kms_wrappingkey_delete.md => stackit_beta_kms_wrapping-key_delete.md} (59%) rename docs/{stackit_beta_kms_wrappingkey_list.md => stackit_beta_kms_wrapping-key_list.md} (77%) diff --git a/docs/stackit_beta_kms.md b/docs/stackit_beta_kms.md index 35fc5b27b..fac6dd01d 100644 --- a/docs/stackit_beta_kms.md +++ b/docs/stackit_beta_kms.md @@ -31,7 +31,7 @@ stackit beta kms [flags] * [stackit beta](./stackit_beta.md) - Contains beta STACKIT CLI commands * [stackit beta kms key](./stackit_beta_kms_key.md) - Manage KMS Keys -* [stackit beta kms keyring](./stackit_beta_kms_keyring.md) - Manage KMS Keyrings -* [stackit beta kms version](./stackit_beta_kms_version.md) - Manage KMS Key versions -* [stackit beta kms wrappingkey](./stackit_beta_kms_wrappingkey.md) - Manage KMS Wrapping Keys +* [stackit beta kms keyring](./stackit_beta_kms_keyring.md) - Manage KMS key rings +* [stackit beta kms version](./stackit_beta_kms_version.md) - Manage KMS key versions +* [stackit beta kms wrapping-key](./stackit_beta_kms_wrapping-key.md) - Manage KMS wrapping keys diff --git a/docs/stackit_beta_kms_key.md b/docs/stackit_beta_kms_key.md index 84080db15..2e6a0dbc2 100644 --- a/docs/stackit_beta_kms_key.md +++ b/docs/stackit_beta_kms_key.md @@ -4,7 +4,7 @@ Manage KMS Keys ### Synopsis -Provides CRUD functionality for Key operations inside the KMS +Provides functionality for Key operations inside the KMS ``` stackit beta kms key [flags] @@ -30,10 +30,10 @@ stackit beta kms key [flags] ### SEE ALSO * [stackit beta kms](./stackit_beta_kms.md) - Provides functionality for KMS -* [stackit beta kms key create](./stackit_beta_kms_key_create.md) - Creates a KMS Key -* [stackit beta kms key delete](./stackit_beta_kms_key_delete.md) - Deletes a KMS Key -* [stackit beta kms key import](./stackit_beta_kms_key_import.md) - Import a KMS Key Version -* [stackit beta kms key list](./stackit_beta_kms_key_list.md) - Lists all KMS Keys -* [stackit beta kms key restore](./stackit_beta_kms_key_restore.md) - Resotre a Key +* [stackit beta kms key create](./stackit_beta_kms_key_create.md) - Creates a KMS key +* [stackit beta kms key delete](./stackit_beta_kms_key_delete.md) - Deletes a KMS key +* [stackit beta kms key import](./stackit_beta_kms_key_import.md) - Import a KMS key +* [stackit beta kms key list](./stackit_beta_kms_key_list.md) - List all KMS keys +* [stackit beta kms key restore](./stackit_beta_kms_key_restore.md) - Resotre a key * [stackit beta kms key rotate](./stackit_beta_kms_key_rotate.md) - Rotate a key diff --git a/docs/stackit_beta_kms_key_create.md b/docs/stackit_beta_kms_key_create.md index 94f7fd3eb..372109c00 100644 --- a/docs/stackit_beta_kms_key_create.md +++ b/docs/stackit_beta_kms_key_create.md @@ -1,10 +1,10 @@ ## stackit beta kms key create -Creates a KMS Key +Creates a KMS key ### Synopsis -Creates a KMS Key. +Creates a KMS key. ``` stackit beta kms key create [flags] @@ -13,23 +13,23 @@ stackit beta kms key create [flags] ### Examples ``` - Create a Symmetric KMS Key - $ stakit beta kms key create --key-ring "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-key-name" --purpose "symmetric_encrypt_decrypt" + Create a Symmetric KMS key + $ stackit beta kms key create --key-ring "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-key-name" --purpose "symmetric_encrypt_decrypt" - Create a Message Authentication KMS Key - $ stakit beta kms key create --key-ring "my-keyring-id" --algorithm "hmac_sha512" --name "my-key-name" --purpose "message_authentication_code" + Create a Message Authentication KMS key + $ stackit beta kms key create --key-ring "my-keyring-id" --algorithm "hmac_sha512" --name "my-key-name" --purpose "message_authentication_code" ``` ### Options ``` --algorithm string En-/Decryption / signing algorithm - --description string Optinal description of the Key + --description string Optional description of the key -h, --help Help for "stackit beta kms key create" --import-only States whether versions can be created or only imported - --key-ring string ID of the KMS Key Ring + --key-ring string ID of the KMS key ring --name string The display name to distinguish multiple keys - --purpose string Purpose of the Key. Enum: 'symmetric_encrypt_decrypt', 'asymmetric_encrypt_decrypt', 'message_authentication_code', 'asymmetric_sign_verify' + --purpose string Purpose of the key. Enum: 'symmetric_encrypt_decrypt', 'asymmetric_encrypt_decrypt', 'message_authentication_code', 'asymmetric_sign_verify' ``` ### Options inherited from parent commands diff --git a/docs/stackit_beta_kms_key_delete.md b/docs/stackit_beta_kms_key_delete.md index 26d7e1eb7..5d2e05275 100644 --- a/docs/stackit_beta_kms_key_delete.md +++ b/docs/stackit_beta_kms_key_delete.md @@ -1,10 +1,10 @@ ## stackit beta kms key delete -Deletes a KMS Key +Deletes a KMS key ### Synopsis -Deletes a KMS Key inside a specific Key Ring. +Deletes a KMS key inside a specific key ring. ``` stackit beta kms key delete [flags] @@ -13,7 +13,7 @@ stackit beta kms key delete [flags] ### Examples ``` - Delete a KMS Key "my-key-id" inside the Key Ring "my-key-ring-id" + Delete a KMS key "my-key-id" inside the key ring "my-key-ring-id" $ stackit beta kms keyring delete --key-ring "my-key-ring-id" --key "my-key-id" ``` diff --git a/docs/stackit_beta_kms_key_import.md b/docs/stackit_beta_kms_key_import.md index 2dbfd2f1c..807632f0b 100644 --- a/docs/stackit_beta_kms_key_import.md +++ b/docs/stackit_beta_kms_key_import.md @@ -1,6 +1,6 @@ ## stackit beta kms key import -Import a KMS Key Version +Import a KMS key ### Synopsis @@ -13,7 +13,7 @@ stackit beta kms key import [flags] ### Examples ``` - Import a new version for the given KMS Key "my-key" + Import a new version for the given KMS key "my-key" $ stakit beta kms key import --key-ring "my-keyring-id" --key "my-key-id" --wrapped-key "base64-encoded-wrapped-key-material" --wrapping-key-id "my-wrapping-key-id" ``` @@ -21,10 +21,10 @@ stackit beta kms key import [flags] ``` -h, --help Help for "stackit beta kms key import" - --key string ID of the KMS Key - --key-ring string ID of the KMS Key Ring + --key string ID of the KMS key + --key-ring string ID of the KMS key ring --wrapped-key string The wrapped key material that has to be imported. Encoded in base64 - --wrapping-key-id string he unique id of the wrapping key the key material has been wrapped with + --wrapping-key-id string The unique id of the wrapping key the key material has been wrapped with ``` ### Options inherited from parent commands diff --git a/docs/stackit_beta_kms_key_list.md b/docs/stackit_beta_kms_key_list.md index 886f1dbfe..818ff8e9e 100644 --- a/docs/stackit_beta_kms_key_list.md +++ b/docs/stackit_beta_kms_key_list.md @@ -1,10 +1,10 @@ ## stackit beta kms key list -Lists all KMS Keys +List all KMS keys ### Synopsis -Lists all KMS Keys inside a key ring. +List all KMS keys inside a key ring. ``` stackit beta kms key list KEYRING_ID [flags] @@ -13,10 +13,10 @@ stackit beta kms key list KEYRING_ID [flags] ### Examples ``` - List all KMS Keys for the key ring "xxx" + List all KMS keys for the key ring "xxx" $ stackit beta kms key list xxx - List all KMS Keys in JSON format + List all KMS keys in JSON format $ stackit beta kms key list xxx --output-format json ``` diff --git a/docs/stackit_beta_kms_key_restore.md b/docs/stackit_beta_kms_key_restore.md index ca40478fe..70c19b824 100644 --- a/docs/stackit_beta_kms_key_restore.md +++ b/docs/stackit_beta_kms_key_restore.md @@ -1,6 +1,6 @@ ## stackit beta kms key restore -Resotre a Key +Resotre a key ### Synopsis @@ -13,7 +13,7 @@ stackit beta kms key restore [flags] ### Examples ``` - Restore a KMS Key "my-key-id" inside the Key Ring "my-key-ring-id" that was scheduled for deletion. + Restore a KMS key "my-key-id" inside the key ring "my-key-ring-id" that was scheduled for deletion. $ stackit beta kms keyring restore --key-ring "my-key-ring-id" --key "my-key-id" ``` diff --git a/docs/stackit_beta_kms_key_rotate.md b/docs/stackit_beta_kms_key_rotate.md index 0beb5eefc..05beab716 100644 --- a/docs/stackit_beta_kms_key_rotate.md +++ b/docs/stackit_beta_kms_key_rotate.md @@ -13,16 +13,16 @@ stackit beta kms key rotate [flags] ### Examples ``` - Rotate a KMS Key "my-key-id" and increase it's version inside the Key Ring "my-key-ring-id". - $ stackit beta kms keyring rotate --key-ring "my-key-ring-id" --key "my-key-id" + Rotate a KMS key "my-key-id" and increase it's version inside the key ring "my-key-ring-id". + $ stackit beta kms key rotate --key-ring "my-key-ring-id" --key "my-key-id" ``` ### Options ``` -h, --help Help for "stackit beta kms key rotate" - --key string ID of the actual Key - --key-ring string ID of the KMS Key Ring where the Key is stored + --key string ID of the actual key + --key-ring string ID of the KMS key Ring where the key is stored ``` ### Options inherited from parent commands diff --git a/docs/stackit_beta_kms_keyring.md b/docs/stackit_beta_kms_keyring.md index 75c548b99..6e65f3a47 100644 --- a/docs/stackit_beta_kms_keyring.md +++ b/docs/stackit_beta_kms_keyring.md @@ -1,10 +1,10 @@ ## stackit beta kms keyring -Manage KMS Keyrings +Manage KMS key rings ### Synopsis -Provides functionality for Keyring operations inside the KMS +Provides functionality for key ring operations inside the KMS ``` stackit beta kms keyring [flags] @@ -30,7 +30,7 @@ stackit beta kms keyring [flags] ### SEE ALSO * [stackit beta kms](./stackit_beta_kms.md) - Provides functionality for KMS -* [stackit beta kms keyring create](./stackit_beta_kms_keyring_create.md) - Creates a KMS Key Ring -* [stackit beta kms keyring delete](./stackit_beta_kms_keyring_delete.md) - Deletes a KMS Keyring -* [stackit beta kms keyring list](./stackit_beta_kms_keyring_list.md) - Lists all KMS Keyrings +* [stackit beta kms keyring create](./stackit_beta_kms_keyring_create.md) - Creates a KMS key ring +* [stackit beta kms keyring delete](./stackit_beta_kms_keyring_delete.md) - Deletes a KMS key ring +* [stackit beta kms keyring list](./stackit_beta_kms_keyring_list.md) - Lists all KMS key rings diff --git a/docs/stackit_beta_kms_keyring_create.md b/docs/stackit_beta_kms_keyring_create.md index 7cda1df7d..0cd309c3a 100644 --- a/docs/stackit_beta_kms_keyring_create.md +++ b/docs/stackit_beta_kms_keyring_create.md @@ -1,10 +1,10 @@ ## stackit beta kms keyring create -Creates a KMS Key Ring +Creates a KMS key ring ### Synopsis -Creates a KMS Key Ring. +Creates a KMS key ring. ``` stackit beta kms keyring create [flags] @@ -16,16 +16,16 @@ stackit beta kms keyring create [flags] Create a KMS key ring $ stakit beta kms keyring create --name my-keyring - Create a KMS Key ring with a description + Create a KMS key ring with a description $ stakit beta kms keyring create --name my-keyring --description my-description ``` ### Options ``` - --description string Optinal description of the Key Ring + --description string Optional description of the key ring -h, --help Help for "stackit beta kms keyring create" - --name string Name of the KMS Key Ring + --name string Name of the KMS key ring ``` ### Options inherited from parent commands @@ -41,5 +41,5 @@ stackit beta kms keyring create [flags] ### SEE ALSO -* [stackit beta kms keyring](./stackit_beta_kms_keyring.md) - Manage KMS Keyrings +* [stackit beta kms keyring](./stackit_beta_kms_keyring.md) - Manage KMS key rings diff --git a/docs/stackit_beta_kms_keyring_delete.md b/docs/stackit_beta_kms_keyring_delete.md index ec5eff147..b3ed9c805 100644 --- a/docs/stackit_beta_kms_keyring_delete.md +++ b/docs/stackit_beta_kms_keyring_delete.md @@ -1,10 +1,10 @@ ## stackit beta kms keyring delete -Deletes a KMS Keyring +Deletes a KMS key ring ### Synopsis -Deletes a KMS Keyring. +Deletes a KMS key ring. ``` stackit beta kms keyring delete KEYRING_ID [flags] @@ -13,7 +13,7 @@ stackit beta kms keyring delete KEYRING_ID [flags] ### Examples ``` - Delete a KMS Keyring with ID "xxx" + Delete a KMS key ring with ID "xxx" $ stackit beta kms keyring delete xxx ``` @@ -36,5 +36,5 @@ stackit beta kms keyring delete KEYRING_ID [flags] ### SEE ALSO -* [stackit beta kms keyring](./stackit_beta_kms_keyring.md) - Manage KMS Keyrings +* [stackit beta kms keyring](./stackit_beta_kms_keyring.md) - Manage KMS key rings diff --git a/docs/stackit_beta_kms_keyring_list.md b/docs/stackit_beta_kms_keyring_list.md index ab71de5d3..c82dae950 100644 --- a/docs/stackit_beta_kms_keyring_list.md +++ b/docs/stackit_beta_kms_keyring_list.md @@ -1,10 +1,10 @@ ## stackit beta kms keyring list -Lists all KMS Keyrings +Lists all KMS key rings ### Synopsis -Lists all KMS Keyrings. +Lists all KMS key rings. ``` stackit beta kms keyring list [flags] @@ -13,10 +13,10 @@ stackit beta kms keyring list [flags] ### Examples ``` - List all KMS Keyrings + List all KMS key rings $ stackit beta kms keyring list - List all KMS Keyrings in JSON format + List all KMS key rings in JSON format $ stackit beta kms keyring list --output-format json ``` @@ -39,5 +39,5 @@ stackit beta kms keyring list [flags] ### SEE ALSO -* [stackit beta kms keyring](./stackit_beta_kms_keyring.md) - Manage KMS Keyrings +* [stackit beta kms keyring](./stackit_beta_kms_keyring.md) - Manage KMS key rings diff --git a/docs/stackit_beta_kms_version.md b/docs/stackit_beta_kms_version.md index e0de4020d..baf9c5ecb 100644 --- a/docs/stackit_beta_kms_version.md +++ b/docs/stackit_beta_kms_version.md @@ -1,10 +1,10 @@ ## stackit beta kms version -Manage KMS Key versions +Manage KMS key versions ### Synopsis -Provides CRUD functionality for Key Version operations inside the KMS +Provides functionality for key version operations inside the KMS ``` stackit beta kms version [flags] @@ -30,9 +30,9 @@ stackit beta kms version [flags] ### SEE ALSO * [stackit beta kms](./stackit_beta_kms.md) - Provides functionality for KMS -* [stackit beta kms version destroy](./stackit_beta_kms_version_destroy.md) - Destroy a Key Versions -* [stackit beta kms version disable](./stackit_beta_kms_version_disable.md) - Disable a Key Versions -* [stackit beta kms version enable](./stackit_beta_kms_version_enable.md) - Enable a Key Versions -* [stackit beta kms version list](./stackit_beta_kms_version_list.md) - Lists all Key Versions -* [stackit beta kms version restore](./stackit_beta_kms_version_restore.md) - Restore a Key Versions +* [stackit beta kms version destroy](./stackit_beta_kms_version_destroy.md) - Destroy a key version +* [stackit beta kms version disable](./stackit_beta_kms_version_disable.md) - Disable a key version +* [stackit beta kms version enable](./stackit_beta_kms_version_enable.md) - Enable a key version +* [stackit beta kms version list](./stackit_beta_kms_version_list.md) - List all key versions +* [stackit beta kms version restore](./stackit_beta_kms_version_restore.md) - Restore a key version diff --git a/docs/stackit_beta_kms_version_destroy.md b/docs/stackit_beta_kms_version_destroy.md index fe9e2a466..d6780f42b 100644 --- a/docs/stackit_beta_kms_version_destroy.md +++ b/docs/stackit_beta_kms_version_destroy.md @@ -1,6 +1,6 @@ ## stackit beta kms version destroy -Destroy a Key Versions +Destroy a key version ### Synopsis @@ -21,8 +21,8 @@ stackit beta kms version destroy [flags] ``` -h, --help Help for "stackit beta kms version destroy" - --key string ID of the Key - --key-ring string ID of the KMS Key Ring + --key string ID of the key + --key-ring string ID of the KMS key ring --version int Version number of the key ``` @@ -39,5 +39,5 @@ stackit beta kms version destroy [flags] ### SEE ALSO -* [stackit beta kms version](./stackit_beta_kms_version.md) - Manage KMS Key versions +* [stackit beta kms version](./stackit_beta_kms_version.md) - Manage KMS key versions diff --git a/docs/stackit_beta_kms_version_disable.md b/docs/stackit_beta_kms_version_disable.md index a8f1f6c1a..43ce36815 100644 --- a/docs/stackit_beta_kms_version_disable.md +++ b/docs/stackit_beta_kms_version_disable.md @@ -1,6 +1,6 @@ ## stackit beta kms version disable -Disable a Key Versions +Disable a key version ### Synopsis @@ -21,8 +21,8 @@ stackit beta kms version disable [flags] ``` -h, --help Help for "stackit beta kms version disable" - --key string ID of the Key - --key-ring string ID of the KMS Key Ring + --key string ID of the rey + --key-ring string ID of the KMS key ring --version int Version number of the key ``` @@ -39,5 +39,5 @@ stackit beta kms version disable [flags] ### SEE ALSO -* [stackit beta kms version](./stackit_beta_kms_version.md) - Manage KMS Key versions +* [stackit beta kms version](./stackit_beta_kms_version.md) - Manage KMS key versions diff --git a/docs/stackit_beta_kms_version_enable.md b/docs/stackit_beta_kms_version_enable.md index 0839b39cf..ea9ac8f82 100644 --- a/docs/stackit_beta_kms_version_enable.md +++ b/docs/stackit_beta_kms_version_enable.md @@ -1,6 +1,6 @@ ## stackit beta kms version enable -Enable a Key Versions +Enable a key version ### Synopsis @@ -21,8 +21,8 @@ stackit beta kms version enable [flags] ``` -h, --help Help for "stackit beta kms version enable" - --key string ID of the Key - --key-ring string ID of the KMS Key Ring + --key string ID of the key + --key-ring string ID of the KMS key ring --version int Version number of the key ``` @@ -39,5 +39,5 @@ stackit beta kms version enable [flags] ### SEE ALSO -* [stackit beta kms version](./stackit_beta_kms_version.md) - Manage KMS Key versions +* [stackit beta kms version](./stackit_beta_kms_version.md) - Manage KMS key versions diff --git a/docs/stackit_beta_kms_version_list.md b/docs/stackit_beta_kms_version_list.md index fef9bd88b..e5fd68e0e 100644 --- a/docs/stackit_beta_kms_version_list.md +++ b/docs/stackit_beta_kms_version_list.md @@ -1,10 +1,10 @@ ## stackit beta kms version list -Lists all Key Versions +List all key versions ### Synopsis -Lists all versions of a given key. +List all versions of a given key. ``` stackit beta kms version list [flags] @@ -24,8 +24,8 @@ stackit beta kms version list [flags] ``` -h, --help Help for "stackit beta kms version list" - --key string ID of the Key - --key-ring string ID of the KMS Key Ring + --key string ID of the key + --key-ring string ID of the KMS key ring ``` ### Options inherited from parent commands @@ -41,5 +41,5 @@ stackit beta kms version list [flags] ### SEE ALSO -* [stackit beta kms version](./stackit_beta_kms_version.md) - Manage KMS Key versions +* [stackit beta kms version](./stackit_beta_kms_version.md) - Manage KMS key versions diff --git a/docs/stackit_beta_kms_version_restore.md b/docs/stackit_beta_kms_version_restore.md index 25b061d63..a6d8a7548 100644 --- a/docs/stackit_beta_kms_version_restore.md +++ b/docs/stackit_beta_kms_version_restore.md @@ -1,6 +1,6 @@ ## stackit beta kms version restore -Restore a Key Versions +Restore a key version ### Synopsis @@ -21,8 +21,8 @@ stackit beta kms version restore [flags] ``` -h, --help Help for "stackit beta kms version restore" - --key string ID of the Key - --key-ring string ID of the KMS Key Ring + --key string ID of the key + --key-ring string ID of the KMS key ring --version int Version number of the key ``` @@ -39,5 +39,5 @@ stackit beta kms version restore [flags] ### SEE ALSO -* [stackit beta kms version](./stackit_beta_kms_version.md) - Manage KMS Key versions +* [stackit beta kms version](./stackit_beta_kms_version.md) - Manage KMS key versions diff --git a/docs/stackit_beta_kms_wrappingkey.md b/docs/stackit_beta_kms_wrapping-key.md similarity index 54% rename from docs/stackit_beta_kms_wrappingkey.md rename to docs/stackit_beta_kms_wrapping-key.md index 4d5548c01..8a2728867 100644 --- a/docs/stackit_beta_kms_wrappingkey.md +++ b/docs/stackit_beta_kms_wrapping-key.md @@ -1,19 +1,19 @@ -## stackit beta kms wrappingkey +## stackit beta kms wrapping-key -Manage KMS Wrapping Keys +Manage KMS wrapping keys ### Synopsis -Provides CRUD functionality for Wrapping Key operations inside the KMS +Provides CRUD functionality for wrapping key operations inside the KMS ``` -stackit beta kms wrappingkey [flags] +stackit beta kms wrapping-key [flags] ``` ### Options ``` - -h, --help Help for "stackit beta kms wrappingkey" + -h, --help Help for "stackit beta kms wrapping-key" ``` ### Options inherited from parent commands @@ -30,7 +30,7 @@ stackit beta kms wrappingkey [flags] ### SEE ALSO * [stackit beta kms](./stackit_beta_kms.md) - Provides functionality for KMS -* [stackit beta kms wrappingkey create](./stackit_beta_kms_wrappingkey_create.md) - Creates a KMS Wrapping Key -* [stackit beta kms wrappingkey delete](./stackit_beta_kms_wrappingkey_delete.md) - Deletes a KMS Wrapping Key -* [stackit beta kms wrappingkey list](./stackit_beta_kms_wrappingkey_list.md) - Lists all KMS Wrapping Keys +* [stackit beta kms wrapping-key create](./stackit_beta_kms_wrapping-key_create.md) - Creates a KMS wrapping key +* [stackit beta kms wrapping-key delete](./stackit_beta_kms_wrapping-key_delete.md) - Deletes a KMS wrapping key +* [stackit beta kms wrapping-key list](./stackit_beta_kms_wrapping-key_list.md) - Lists all KMS Wrapping Keys diff --git a/docs/stackit_beta_kms_wrappingkey_create.md b/docs/stackit_beta_kms_wrapping-key_create.md similarity index 68% rename from docs/stackit_beta_kms_wrappingkey_create.md rename to docs/stackit_beta_kms_wrapping-key_create.md index a8fb90734..addafc936 100644 --- a/docs/stackit_beta_kms_wrappingkey_create.md +++ b/docs/stackit_beta_kms_wrapping-key_create.md @@ -1,22 +1,22 @@ -## stackit beta kms wrappingkey create +## stackit beta kms wrapping-key create -Creates a KMS Wrapping Key +Creates a KMS wrapping key ### Synopsis -Creates a KMS Wrapping Key. +Creates a KMS wrapping key. ``` -stackit beta kms wrappingkey create [flags] +stackit beta kms wrapping-key create [flags] ``` ### Examples ``` - Create a Symmetric KMS Wrapping Key + Create a Symmetric KMS wrapping key $ stakit beta kms wrappingkey create --key-ring "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-wrapping-key-name" --purpose "wrap_symmetric_key" - Create an Asymmetric KMS Wrapping Key with a description + Create an Asymmetric KMS wrapping key with a description $ stakit beta kms wrappingkey create --key-ring "my-keyring-id" --algorithm "hmac_sha256" --name "my-wrapping-key-name" --description "my-description" --purpose "wrap_asymmetric_key" ``` @@ -24,11 +24,11 @@ stackit beta kms wrappingkey create [flags] ``` --algorithm string En-/Decryption algorithm - --description string Optinal description of the Wrapping Key - -h, --help Help for "stackit beta kms wrappingkey create" - --key-ring string ID of the KMS Key Ring + --description string Optional description of the wrapping key + -h, --help Help for "stackit beta kms wrapping-key create" + --key-ring string ID of the KMS key ring --name string The display name to distinguish multiple wrapping keys - --purpose string Purpose of the Wrapping Key. Enum: 'wrap_symmetric_key', 'wrap_asymmetric_key' + --purpose string Purpose of the wrapping key. Enum: 'wrap_symmetric_key', 'wrap_asymmetric_key' ``` ### Options inherited from parent commands @@ -44,5 +44,5 @@ stackit beta kms wrappingkey create [flags] ### SEE ALSO -* [stackit beta kms wrappingkey](./stackit_beta_kms_wrappingkey.md) - Manage KMS Wrapping Keys +* [stackit beta kms wrapping-key](./stackit_beta_kms_wrapping-key.md) - Manage KMS wrapping keys diff --git a/docs/stackit_beta_kms_wrappingkey_delete.md b/docs/stackit_beta_kms_wrapping-key_delete.md similarity index 59% rename from docs/stackit_beta_kms_wrappingkey_delete.md rename to docs/stackit_beta_kms_wrapping-key_delete.md index e1813b7d8..9695006e5 100644 --- a/docs/stackit_beta_kms_wrappingkey_delete.md +++ b/docs/stackit_beta_kms_wrapping-key_delete.md @@ -1,28 +1,28 @@ -## stackit beta kms wrappingkey delete +## stackit beta kms wrapping-key delete -Deletes a KMS Wrapping Key +Deletes a KMS wrapping key ### Synopsis -Deletes a KMS Wrapping Key inside a specific Key Ring. +Deletes a KMS wrapping key inside a specific key ring. ``` -stackit beta kms wrappingkey delete [flags] +stackit beta kms wrapping-key delete [flags] ``` ### Examples ``` - Delete a KMS Wrapping Key "my-wrapping-key-id" inside the Key Ring "my-key-ring-id" + Delete a KMS wrapping key "my-wrapping-key-id" inside the key ring "my-key-ring-id" $ stackit beta kms keyring delete --key-ring "my-key-ring-id" --wrapping-key "my-wrapping-key-id" ``` ### Options ``` - -h, --help Help for "stackit beta kms wrappingkey delete" - --key-ring string ID of the KMS Key Ring where the Wrapping Key is stored - --wrapping-key string ID of the actual Wrapping Key + -h, --help Help for "stackit beta kms wrapping-key delete" + --key-ring string ID of the KMS key ring where the wrapping key is stored + --wrapping-key string ID of the actual wrapping key ``` ### Options inherited from parent commands @@ -38,5 +38,5 @@ stackit beta kms wrappingkey delete [flags] ### SEE ALSO -* [stackit beta kms wrappingkey](./stackit_beta_kms_wrappingkey.md) - Manage KMS Wrapping Keys +* [stackit beta kms wrapping-key](./stackit_beta_kms_wrapping-key.md) - Manage KMS wrapping keys diff --git a/docs/stackit_beta_kms_wrappingkey_list.md b/docs/stackit_beta_kms_wrapping-key_list.md similarity index 77% rename from docs/stackit_beta_kms_wrappingkey_list.md rename to docs/stackit_beta_kms_wrapping-key_list.md index 8cf83d10d..16a6b50a6 100644 --- a/docs/stackit_beta_kms_wrappingkey_list.md +++ b/docs/stackit_beta_kms_wrapping-key_list.md @@ -1,4 +1,4 @@ -## stackit beta kms wrappingkey list +## stackit beta kms wrapping-key list Lists all KMS Wrapping Keys @@ -7,7 +7,7 @@ Lists all KMS Wrapping Keys Lists all KMS Wrapping Keys inside a key ring. ``` -stackit beta kms wrappingkey list KEYRING_ID [flags] +stackit beta kms wrapping-key list KEYRING_ID [flags] ``` ### Examples @@ -23,7 +23,7 @@ stackit beta kms wrappingkey list KEYRING_ID [flags] ### Options ``` - -h, --help Help for "stackit beta kms wrappingkey list" + -h, --help Help for "stackit beta kms wrapping-key list" ``` ### Options inherited from parent commands @@ -39,5 +39,5 @@ stackit beta kms wrappingkey list KEYRING_ID [flags] ### SEE ALSO -* [stackit beta kms wrappingkey](./stackit_beta_kms_wrappingkey.md) - Manage KMS Wrapping Keys +* [stackit beta kms wrapping-key](./stackit_beta_kms_wrapping-key.md) - Manage KMS wrapping keys From 056ffdbd3db6d21f87907db2c99385c7dfd85622 Mon Sep 17 00:00:00 2001 From: Jan Sternagel Date: Tue, 7 Oct 2025 08:50:26 +0200 Subject: [PATCH 22/52] remove comments --- internal/cmd/beta/kms/key/create/create.go | 3 --- internal/cmd/beta/kms/key/importKey/importKey.go | 1 - internal/cmd/beta/kms/wrappingkey/create/create.go | 2 -- 3 files changed, 6 deletions(-) diff --git a/internal/cmd/beta/kms/key/create/create.go b/internal/cmd/beta/kms/key/create/create.go index ce63e45c9..5a4ab9865 100644 --- a/internal/cmd/beta/kms/key/create/create.go +++ b/internal/cmd/beta/kms/key/create/create.go @@ -120,8 +120,6 @@ func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { return nil, &cliErr.ProjectIdError{} } - // What checks could this need? - // I would rather let the creation fail instead of checking all possible algorithms model := inputModel{ GlobalFlagModel: globalFlags, KeyRingId: flags.FlagToStringValue(p, cmd, keyRingIdFlag), @@ -151,7 +149,6 @@ type kmsKeyClient interface { func buildRequest(ctx context.Context, model *inputModel, apiClient kmsKeyClient) (kms.ApiCreateKeyRequest, error) { req := apiClient.CreateKey(ctx, model.ProjectId, model.Region, model.KeyRingId) - // Question: Should there be additional checks here? req = req.CreateKeyPayload(kms.CreateKeyPayload{ DisplayName: model.Name, Description: model.Description, diff --git a/internal/cmd/beta/kms/key/importKey/importKey.go b/internal/cmd/beta/kms/key/importKey/importKey.go index 1603b983d..46c215680 100644 --- a/internal/cmd/beta/kms/key/importKey/importKey.go +++ b/internal/cmd/beta/kms/key/importKey/importKey.go @@ -142,7 +142,6 @@ type kmsKeyClient interface { func buildRequest(ctx context.Context, model *inputModel, apiClient kmsKeyClient) (kms.ApiImportKeyRequest, error) { req := apiClient.ImportKey(ctx, model.ProjectId, model.Region, model.KeyRingId, model.KeyId) - // Question: Should there be additional checks here? req = req.ImportKeyPayload(kms.ImportKeyPayload{ WrappedKey: model.WrappedKey, WrappingKeyId: model.WrappingKeyId, diff --git a/internal/cmd/beta/kms/wrappingkey/create/create.go b/internal/cmd/beta/kms/wrappingkey/create/create.go index 3a4009b90..1c8bbe070 100644 --- a/internal/cmd/beta/kms/wrappingkey/create/create.go +++ b/internal/cmd/beta/kms/wrappingkey/create/create.go @@ -147,8 +147,6 @@ type kmsWrappingKeyClient interface { func buildRequest(ctx context.Context, model *inputModel, apiClient kmsWrappingKeyClient) (kms.ApiCreateWrappingKeyRequest, error) { req := apiClient.CreateWrappingKey(ctx, model.ProjectId, model.Region, model.KeyRingId) - // Question: Should there be additional checks here? - req = req.CreateWrappingKeyPayload(kms.CreateWrappingKeyPayload{ DisplayName: model.Name, Description: model.Description, From 2bac600d54568c9cb1a9870d579b6bbf23de480d Mon Sep 17 00:00:00 2001 From: Jan Sternagel Date: Tue, 7 Oct 2025 09:17:14 +0200 Subject: [PATCH 23/52] stakit -> stackit --- internal/cmd/beta/kms/key/importKey/importKey.go | 2 +- internal/cmd/beta/kms/keyring/create/create.go | 4 ++-- internal/cmd/beta/kms/wrappingkey/create/create.go | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/internal/cmd/beta/kms/key/importKey/importKey.go b/internal/cmd/beta/kms/key/importKey/importKey.go index 46c215680..959c65f97 100644 --- a/internal/cmd/beta/kms/key/importKey/importKey.go +++ b/internal/cmd/beta/kms/key/importKey/importKey.go @@ -47,7 +47,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Example: examples.Build( examples.NewExample( `Import a new version for the given KMS key "my-key"`, - `$ stakit beta kms key import --key-ring "my-keyring-id" --key "my-key-id" --wrapped-key "base64-encoded-wrapped-key-material" --wrapping-key-id "my-wrapping-key-id"`), + `$ stackit beta kms key import --key-ring "my-keyring-id" --key "my-key-id" --wrapped-key "base64-encoded-wrapped-key-material" --wrapping-key-id "my-wrapping-key-id"`), ), RunE: func(cmd *cobra.Command, _ []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/keyring/create/create.go b/internal/cmd/beta/kms/keyring/create/create.go index df3e9f756..b5ff5a5b7 100644 --- a/internal/cmd/beta/kms/keyring/create/create.go +++ b/internal/cmd/beta/kms/keyring/create/create.go @@ -43,10 +43,10 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Example: examples.Build( examples.NewExample( `Create a KMS key ring`, - "$ stakit beta kms keyring create --name my-keyring"), + "$ stackit beta kms keyring create --name my-keyring"), examples.NewExample( `Create a KMS key ring with a description`, - "$ stakit beta kms keyring create --name my-keyring --description my-description"), + "$ stackit beta kms keyring create --name my-keyring --description my-description"), ), RunE: func(cmd *cobra.Command, _ []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/wrappingkey/create/create.go b/internal/cmd/beta/kms/wrappingkey/create/create.go index 1c8bbe070..af1f4ae46 100644 --- a/internal/cmd/beta/kms/wrappingkey/create/create.go +++ b/internal/cmd/beta/kms/wrappingkey/create/create.go @@ -51,10 +51,10 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Example: examples.Build( examples.NewExample( `Create a Symmetric KMS wrapping key`, - `$ stakit beta kms wrappingkey create --key-ring "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-wrapping-key-name" --purpose "wrap_symmetric_key"`), + `$ stackit beta kms wrappingkey create --key-ring "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-wrapping-key-name" --purpose "wrap_symmetric_key"`), examples.NewExample( `Create an Asymmetric KMS wrapping key with a description`, - `$ stakit beta kms wrappingkey create --key-ring "my-keyring-id" --algorithm "hmac_sha256" --name "my-wrapping-key-name" --description "my-description" --purpose "wrap_asymmetric_key"`), + `$ stackit beta kms wrappingkey create --key-ring "my-keyring-id" --algorithm "hmac_sha256" --name "my-wrapping-key-name" --description "my-description" --purpose "wrap_asymmetric_key"`), ), RunE: func(cmd *cobra.Command, _ []string) error { ctx := context.Background() From d4a1a1ecf13e8a992d64ce86541da42517db8860 Mon Sep 17 00:00:00 2001 From: Jan Sternagel Date: Tue, 7 Oct 2025 09:19:30 +0200 Subject: [PATCH 24/52] clearner loop --- internal/cmd/beta/kms/key/list/list.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/internal/cmd/beta/kms/key/list/list.go b/internal/cmd/beta/kms/key/list/list.go index 51b7a7345..c1f4d49ca 100644 --- a/internal/cmd/beta/kms/key/list/list.go +++ b/internal/cmd/beta/kms/key/list/list.go @@ -125,8 +125,7 @@ func outputResult(p *print.Printer, outputFormat, projectId, keyRingId string, k table := tables.NewTable() table.SetHeader("ID", "NAME", "SCOPE", "ALGORITHM", "DELETION DATE", "STATUS") - for i := range keys { - key := keys[i] + for _, key := range keys { table.AddRow( utils.PtrString(key.Id), utils.PtrString(key.DisplayName), From 03406f1c8273d3200c21fa51ce0828eb175e7637 Mon Sep 17 00:00:00 2001 From: Jan Sternagel Date: Tue, 7 Oct 2025 09:19:44 +0200 Subject: [PATCH 25/52] fix spelling --- internal/cmd/beta/kms/key/restore/restore.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/cmd/beta/kms/key/restore/restore.go b/internal/cmd/beta/kms/key/restore/restore.go index 1b9622769..10465df44 100644 --- a/internal/cmd/beta/kms/key/restore/restore.go +++ b/internal/cmd/beta/kms/key/restore/restore.go @@ -34,7 +34,7 @@ type inputModel struct { func NewCmd(params *params.CmdParams) *cobra.Command { cmd := &cobra.Command{ Use: "restore", - Short: "Resotre a key", + Short: "Restore a key", Long: "Restores the given key from being deleted.", Args: args.NoArgs, Example: examples.Build( From bba5217cfac082625a45aaab85ecdd4ada6d3182 Mon Sep 17 00:00:00 2001 From: Jan Sternagel Date: Tue, 7 Oct 2025 16:05:53 +0200 Subject: [PATCH 26/52] 1. Corrected the output format for all requests 2. Switched flags to args and vice versa to keep the clean format all the way --- internal/cmd/beta/kms/key/create/create.go | 23 ++-- .../cmd/beta/kms/key/create/create_test.go | 12 ++ internal/cmd/beta/kms/key/delete/delete.go | 77 +++++------- .../cmd/beta/kms/key/delete/delete_test.go | 82 +++++++------ .../cmd/beta/kms/key/importKey/importKey.go | 40 +++--- .../beta/kms/key/importKey/importKey_test.go | 69 +++++++---- internal/cmd/beta/kms/key/list/list.go | 35 +++--- internal/cmd/beta/kms/key/list/list_test.go | 58 ++++----- internal/cmd/beta/kms/key/restore/restore.go | 76 +++++------- .../cmd/beta/kms/key/restore/restore_test.go | 77 +++++++----- internal/cmd/beta/kms/key/rotate/rotate.go | 31 ++--- .../cmd/beta/kms/key/rotate/rotate_test.go | 63 ++++++---- .../cmd/beta/kms/keyring/create/create.go | 6 +- .../cmd/beta/kms/keyring/delete/delete.go | 46 +++---- .../beta/kms/keyring/delete/delete_test.go | 14 +-- internal/cmd/beta/kms/keyring/list/list.go | 6 +- .../cmd/beta/kms/version/destroy/destroy.go | 104 ++++++++-------- .../beta/kms/version/destroy/destroy_test.go | 113 +++++++++-------- .../cmd/beta/kms/version/disable/disable.go | 116 ++++++++---------- .../beta/kms/version/disable/disable_test.go | 114 +++++++++-------- .../cmd/beta/kms/version/enable/enable.go | 107 ++++++++-------- .../beta/kms/version/enable/enable_test.go | 114 +++++++++-------- internal/cmd/beta/kms/version/list/list.go | 10 +- .../cmd/beta/kms/version/restore/restore.go | 101 +++++++-------- .../beta/kms/version/restore/restore_test.go | 114 +++++++++-------- .../cmd/beta/kms/wrappingkey/create/create.go | 24 ++-- .../kms/wrappingkey/create/create_test.go | 12 ++ .../cmd/beta/kms/wrappingkey/delete/delete.go | 82 ++++--------- .../kms/wrappingkey/delete/delete_test.go | 116 ++++++++---------- .../cmd/beta/kms/wrappingkey/list/list.go | 43 ++++--- .../beta/kms/wrappingkey/list/list_test.go | 66 ++++------ 31 files changed, 975 insertions(+), 976 deletions(-) diff --git a/internal/cmd/beta/kms/key/create/create.go b/internal/cmd/beta/kms/key/create/create.go index 5a4ab9865..abea08588 100644 --- a/internal/cmd/beta/kms/key/create/create.go +++ b/internal/cmd/beta/kms/key/create/create.go @@ -24,13 +24,14 @@ import ( ) const ( - keyRingIdFlag = "key-ring" + keyRingIdFlag = "key-ring-id" algorithmFlag = "algorithm" descriptionFlag = "description" displayNameFlag = "name" importOnlyFlag = "import-only" purposeFlag = "purpose" + protectionFlag = "protection" ) type inputModel struct { @@ -42,6 +43,7 @@ type inputModel struct { Name *string ImportOnly bool // Default false Purpose *string + Protection *string } func NewCmd(params *params.CmdParams) *cobra.Command { @@ -53,10 +55,10 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Example: examples.Build( examples.NewExample( `Create a Symmetric KMS key`, - `$ stackit beta kms key create --key-ring "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-key-name" --purpose "symmetric_encrypt_decrypt"`), + `$ stackit beta kms key create --key-ring "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-key-name" --purpose "asymmetric_encrypt_decrypt" --protection "software"`), examples.NewExample( `Create a Message Authentication KMS key`, - `$ stackit beta kms key create --key-ring "my-keyring-id" --algorithm "hmac_sha512" --name "my-key-name" --purpose "message_authentication_code"`), + `$ stackit beta kms key create --key-ring "my-keyring-id" --algorithm "hmac_sha512" --name "my-key-name" --purpose "message_authentication_code" --protection "software"`), ), RunE: func(cmd *cobra.Command, _ []string) error { ctx := context.Background() @@ -87,10 +89,6 @@ func NewCmd(params *params.CmdParams) *cobra.Command { // Call API req, _ := buildRequest(ctx, model, apiClient) - if err != nil { - return err - } - key, err := req.Execute() if err != nil { return fmt.Errorf("create KMS key: %w", err) @@ -128,6 +126,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { Description: flags.FlagToStringPointer(p, cmd, descriptionFlag), ImportOnly: flags.FlagToBoolValue(p, cmd, importOnlyFlag), Purpose: flags.FlagToStringPointer(p, cmd, purposeFlag), + Protection: flags.FlagToStringPointer(p, cmd, protectionFlag), } if p.IsVerbosityDebug() { @@ -155,6 +154,7 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient kmsKeyClient Algorithm: kms.CreateKeyPayloadGetAlgorithmAttributeType(model.Algorithm), Purpose: kms.CreateKeyPayloadGetPurposeAttributeType(model.Purpose), ImportOnly: &model.ImportOnly, + Protection: kms.CreateKeyPayloadGetProtectionAttributeType(model.Protection), }) return req, nil } @@ -171,7 +171,6 @@ func outputResult(p *print.Printer, outputFormat, projectLabel string, resp *kms return fmt.Errorf("marshal KMS key: %w", err) } p.Outputln(string(details)) - return nil case print.YAMLOutputFormat: details, err := yaml.MarshalWithOptions(resp, yaml.IndentSequence(true), yaml.UseJSONMarshaler()) @@ -179,12 +178,11 @@ func outputResult(p *print.Printer, outputFormat, projectLabel string, resp *kms return fmt.Errorf("marshal KMS key: %w", err) } p.Outputln(string(details)) - return nil default: - p.Outputf("Created key for project %q. key ID: %s\n", projectLabel, utils.PtrString(resp.Id)) - return nil + p.Outputf("Created the key '%s' for project %q. Key ID: %s\n", utils.PtrString(resp.DisplayName), projectLabel, utils.PtrString(resp.Id)) } + return nil } func configureFlags(cmd *cobra.Command) { @@ -194,7 +192,8 @@ func configureFlags(cmd *cobra.Command) { cmd.Flags().String(descriptionFlag, "", "Optional description of the key") cmd.Flags().Bool(importOnlyFlag, false, "States whether versions can be created or only imported") cmd.Flags().String(purposeFlag, "", "Purpose of the key. Enum: 'symmetric_encrypt_decrypt', 'asymmetric_encrypt_decrypt', 'message_authentication_code', 'asymmetric_sign_verify' ") + cmd.Flags().String(protectionFlag, "", "The underlying system that is responsible for protecting the key material. Value: 'software'") - err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, algorithmFlag, purposeFlag, displayNameFlag) + err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, algorithmFlag, purposeFlag, displayNameFlag, protectionFlag) cobra.CheckErr(err) } diff --git a/internal/cmd/beta/kms/key/create/create_test.go b/internal/cmd/beta/kms/key/create/create_test.go index 69e4df392..82394b8cf 100644 --- a/internal/cmd/beta/kms/key/create/create_test.go +++ b/internal/cmd/beta/kms/key/create/create_test.go @@ -22,6 +22,7 @@ const ( testPurpose = "asymmetric_encrypt_decrypt" testDescription = "my key description" testImportOnly = "true" + testProtection = "software" ) type testCtxKey struct{} @@ -44,6 +45,7 @@ func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]st purposeFlag: testPurpose, descriptionFlag: testDescription, importOnlyFlag: testImportOnly, + protectionFlag: testProtection, } for _, mod := range mods { mod(flagValues) @@ -65,6 +67,7 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { Purpose: utils.Ptr(testPurpose), Description: utils.Ptr(testDescription), ImportOnly: true, // Watch out: ImportOnly is not testImportOnly! + Protection: utils.Ptr(testProtection), } for _, mod := range mods { mod(model) @@ -81,6 +84,7 @@ func fixtureRequest(mods ...func(request *kms.ApiCreateKeyRequest)) kms.ApiCreat Purpose: kms.CreateKeyPayloadGetPurposeAttributeType(utils.Ptr(testPurpose)), Description: utils.Ptr(testDescription), ImportOnly: utils.Ptr(true), + Protection: kms.CreateKeyPayloadGetProtectionAttributeType(utils.Ptr(testProtection)), }) for _, mod := range mods { @@ -161,6 +165,13 @@ func TestParseInput(t *testing.T) { }), isValid: false, }, + { + description: "protection missing (required)", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, protectionFlag) + }), + isValid: false, + }, { description: "name missing (required)", flagValues: fixtureFlagValues(func(flagValues map[string]string) { @@ -248,6 +259,7 @@ func TestBuildRequest(t *testing.T) { Purpose: kms.CreateKeyPayloadGetPurposeAttributeType(utils.Ptr(testPurpose)), Description: nil, ImportOnly: utils.Ptr(false), + Protection: kms.CreateKeyPayloadGetProtectionAttributeType(utils.Ptr(testProtection)), }), }, } diff --git a/internal/cmd/beta/kms/key/delete/delete.go b/internal/cmd/beta/kms/key/delete/delete.go index d45d11391..d5254c4ca 100644 --- a/internal/cmd/beta/kms/key/delete/delete.go +++ b/internal/cmd/beta/kms/key/delete/delete.go @@ -4,7 +4,6 @@ import ( "context" "encoding/json" "fmt" - "time" "github.com/goccy/go-yaml" "github.com/spf13/cobra" @@ -16,36 +15,38 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/print" kmsUtils "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/utils" + "github.com/stackitcloud/stackit-cli/internal/pkg/utils" "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/client" "github.com/stackitcloud/stackit-sdk-go/services/kms" ) const ( - keyRingIdFlag = "key-ring" - keyIdFlag = "key" + keyIdArg = "KEY_ID" + + keyRingIdFlag = "key-ring-id" ) type inputModel struct { *globalflags.GlobalFlagModel - KeyRingId string KeyId string + KeyRingId string } func NewCmd(params *params.CmdParams) *cobra.Command { cmd := &cobra.Command{ - Use: "delete", + Use: fmt.Sprintf("delete %s", keyIdArg), Short: "Deletes a KMS key", Long: "Deletes a KMS key inside a specific key ring.", - Args: args.NoArgs, + Args: args.SingleArg(keyIdArg, utils.ValidateUUID), Example: examples.Build( examples.NewExample( `Delete a KMS key "my-key-id" inside the key ring "my-key-ring-id"`, - `$ stackit beta kms keyring delete --key-ring "my-key-ring-id" --key "my-key-id"`), + `$ stackit beta kms keyring delete "my-key-id" --key-ring "my-key-ring-id"`), ), - RunE: func(cmd *cobra.Command, _ []string) error { + RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() - model, err := parseInput(params.Printer, cmd) + model, err := parseInput(params.Printer, cmd, args) if err != nil { return err } @@ -79,12 +80,12 @@ func NewCmd(params *params.CmdParams) *cobra.Command { // Don't wait for a month until the deletion was performed. // Just print the deletion date. - deletionDate, err := kmsUtils.GetKeyDeletionDate(ctx, apiClient, model.ProjectId, model.Region, model.KeyRingId, model.KeyId) + resp, err := apiClient.GetKeyExecute(ctx, model.ProjectId, model.Region, model.KeyRingId, model.KeyId) if err != nil { - return err + params.Printer.Debug(print.ErrorLevel, "get key: %v", err) } - return outputResult(params.Printer, model.OutputFormat, model.KeyId, keyName, deletionDate) + return outputResult(params.Printer, model.OutputFormat, resp) }, } @@ -92,7 +93,9 @@ func NewCmd(params *params.CmdParams) *cobra.Command { return cmd } -func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { +func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inputModel, error) { + keyId := inputArgs[0] + globalFlags := globalflags.Parse(p, cmd) if globalFlags.ProjectId == "" { return nil, &errors.ProjectIdError{} @@ -101,7 +104,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { model := inputModel{ GlobalFlagModel: globalFlags, KeyRingId: flags.FlagToStringValue(p, cmd, keyRingIdFlag), - KeyId: flags.FlagToStringValue(p, cmd, keyIdFlag), + KeyId: keyId, } if p.IsVerbosityDebug() { @@ -123,53 +126,31 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClie func configureFlags(cmd *cobra.Command) { cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS Key Ring where the Key is stored") - cmd.Flags().Var(flags.UUIDFlag(), keyIdFlag, "ID of the actual Key") - err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, keyIdFlag) + err := flags.MarkFlagsRequired(cmd, keyRingIdFlag) cobra.CheckErr(err) } -func outputResult(p *print.Printer, outputFormat, keyId, keyName string, deletionDate time.Time) error { +func outputResult(p *print.Printer, outputFormat string, resp *kms.Key) error { + if resp == nil { + return fmt.Errorf("response from 'GetKeyExecute()' is nil") + } + switch outputFormat { case print.JSONOutputFormat: - details := struct { - KeyId string `json:"keyId"` - KeyName string `json:"keyName"` - Status string `json:"status"` - DeletionDate time.Time `json:"deletionDate"` - }{ - KeyId: keyId, - KeyName: keyName, - Status: "Deletion Scheduled", - DeletionDate: deletionDate, - } - b, err := json.MarshalIndent(details, "", " ") + details, err := json.MarshalIndent(resp, "", " ") if err != nil { return fmt.Errorf("marshal output to JSON: %w", err) } - p.Outputln(string(b)) - return nil - + p.Outputln(string(details)) case print.YAMLOutputFormat: - details := struct { - KeyId string `yaml:"keyId"` - KeyName string `yaml:"keyName"` - Status string `yaml:"status"` - DeletionDate time.Time `yaml:"deletionDate"` - }{ - KeyId: keyId, - KeyName: keyName, - Status: "Deletion Scheduled", - DeletionDate: deletionDate, - } - b, err := yaml.Marshal(details) + details, err := yaml.MarshalWithOptions(resp, yaml.IndentSequence(true), yaml.UseJSONMarshaler()) if err != nil { return fmt.Errorf("marshal output to YAML: %w", err) } - p.Outputln(string(b)) - return nil + p.Outputln(string(details)) default: - p.Outputf("Deletion of KMS key %q scheduled successfully for the deletion date: %q\n", keyName, deletionDate) - return nil + p.Outputf("Deletion of KMS key %s scheduled successfully for the deletion date: %s\n", utils.PtrString(resp.DisplayName), utils.PtrString(resp.DeletionDate)) } + return nil } diff --git a/internal/cmd/beta/kms/key/delete/delete_test.go b/internal/cmd/beta/kms/key/delete/delete_test.go index 8a35ebcfa..a3fd66425 100644 --- a/internal/cmd/beta/kms/key/delete/delete_test.go +++ b/internal/cmd/beta/kms/key/delete/delete_test.go @@ -3,12 +3,10 @@ package delete import ( "context" "testing" - "time" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/uuid" - "github.com/spf13/cobra" "github.com/stackitcloud/stackit-cli/internal/cmd/params" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/print" @@ -29,13 +27,23 @@ var ( testKeyId = uuid.NewString() ) +// Args +func fixtureArgValues(mods ...func(argValues []string)) []string { + argValues := []string{ + testKeyId, + } + for _, mod := range mods { + mod(argValues) + } + return argValues +} + // Flags func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]string { flagValues := map[string]string{ globalflags.ProjectIdFlag: testProjectId, globalflags.RegionFlag: testRegion, keyRingIdFlag: testKeyRingId, - keyIdFlag: testKeyId, } for _, mod := range mods { mod(flagValues) @@ -72,23 +80,33 @@ func fixtureRequest(mods ...func(request *kms.ApiDeleteKeyRequest)) kms.ApiDelet func TestParseInput(t *testing.T) { tests := []struct { description string + argValues []string flagValues map[string]string isValid bool expectedModel *inputModel }{ { description: "base", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(), expectedModel: fixtureInputModel(), isValid: true, }, + { + description: "no args (keyId)", + argValues: []string{}, + flagValues: fixtureFlagValues(), + isValid: false, + }, { description: "no values", + argValues: fixtureArgValues(), flagValues: map[string]string{}, isValid: false, }, { description: "project id missing", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { delete(flagValues, globalflags.ProjectIdFlag) }), @@ -96,6 +114,7 @@ func TestParseInput(t *testing.T) { }, { description: "project id invalid 1", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[globalflags.ProjectIdFlag] = "" }), @@ -103,6 +122,7 @@ func TestParseInput(t *testing.T) { }, { description: "project id invalid 2", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[globalflags.ProjectIdFlag] = "invalid-uuid" }), @@ -110,6 +130,7 @@ func TestParseInput(t *testing.T) { }, { description: "key ring id missing", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { delete(flagValues, keyRingIdFlag) }), @@ -117,6 +138,7 @@ func TestParseInput(t *testing.T) { }, { description: "key ring id invalid 1", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[keyRingIdFlag] = "" }), @@ -124,43 +146,42 @@ func TestParseInput(t *testing.T) { }, { description: "key ring id invalid 2", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[keyRingIdFlag] = "invalid-uuid" }), isValid: false, }, - { - description: "key id missing", - flagValues: fixtureFlagValues(func(flagValues map[string]string) { - delete(flagValues, keyIdFlag) - }), - isValid: false, - }, { description: "key id invalid 1", - flagValues: fixtureFlagValues(func(flagValues map[string]string) { - flagValues[keyIdFlag] = "" - }), - isValid: false, + argValues: []string{""}, + flagValues: fixtureFlagValues(), + isValid: false, }, { description: "key id invalid 2", - flagValues: fixtureFlagValues(func(flagValues map[string]string) { - flagValues[keyIdFlag] = "invalid-uuid" - }), - isValid: false, + argValues: []string{"invalid-uuid"}, + flagValues: fixtureFlagValues(), + isValid: false, }, } for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { - cmd := &cobra.Command{} + p := print.NewPrinter() + cmd := NewCmd(¶ms.CmdParams{Printer: p}) err := globalflags.Configure(cmd.Flags()) if err != nil { t.Fatalf("configure global flags: %v", err) } - configureFlags(cmd) + err = cmd.ValidateArgs(tt.argValues) + if err != nil { + if !tt.isValid { + return + } + t.Fatalf("error validating args: %v", err) + } for flag, value := range tt.flagValues { err := cmd.Flags().Set(flag, value) @@ -180,8 +201,7 @@ func TestParseInput(t *testing.T) { t.Fatalf("error validating flags: %v", err) } - p := print.NewPrinter() - model, err := parseInput(p, cmd) + model, err := parseInput(p, cmd, tt.argValues) if err != nil { if !tt.isValid { return @@ -233,31 +253,23 @@ func TestOutputResult(t *testing.T) { description string wantErr bool outputFormat string - keyId string - keyName string - deltionDate time.Time + resp *kms.Key }{ { description: "default output", - keyId: uuid.NewString(), - keyName: uuid.NewString(), - deltionDate: time.Now(), + resp: &kms.Key{}, wantErr: false, }, { description: "json output", outputFormat: print.JSONOutputFormat, - keyId: uuid.NewString(), - keyName: uuid.NewString(), - deltionDate: time.Now(), + resp: &kms.Key{}, wantErr: false, }, { description: "yaml output", outputFormat: print.YAMLOutputFormat, - keyId: uuid.NewString(), - keyName: uuid.NewString(), - deltionDate: time.Now(), + resp: &kms.Key{}, wantErr: false, }, } @@ -266,7 +278,7 @@ func TestOutputResult(t *testing.T) { p.Cmd = NewCmd(¶ms.CmdParams{Printer: p}) for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { - err := outputResult(p, tt.outputFormat, tt.keyId, tt.keyName, tt.deltionDate) + err := outputResult(p, tt.outputFormat, tt.resp) if (err != nil) != tt.wantErr { t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr) } diff --git a/internal/cmd/beta/kms/key/importKey/importKey.go b/internal/cmd/beta/kms/key/importKey/importKey.go index 959c65f97..2097c3e68 100644 --- a/internal/cmd/beta/kms/key/importKey/importKey.go +++ b/internal/cmd/beta/kms/key/importKey/importKey.go @@ -13,6 +13,7 @@ import ( cliErr "github.com/stackitcloud/stackit-cli/internal/pkg/errors" "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/client" kmsUtils "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/utils" + "github.com/stackitcloud/stackit-cli/internal/pkg/utils" "github.com/stackitcloud/stackit-cli/internal/pkg/examples" "github.com/stackitcloud/stackit-cli/internal/pkg/flags" @@ -22,36 +23,35 @@ import ( ) const ( - keyRingIdFlag = "key-ring" - keyIdFlag = "key" + keyIdArg = "KEY_ID" + keyRingIdFlag = "key-ring-id" wrappedKeyFlag = "wrapped-key" wrappingKeyIdFlag = "wrapping-key-id" ) type inputModel struct { *globalflags.GlobalFlagModel - KeyRingId string - KeyId string - + KeyRingId string + KeyId string WrappedKey *string WrappingKeyId *string } func NewCmd(params *params.CmdParams) *cobra.Command { cmd := &cobra.Command{ - Use: "import", + Use: fmt.Sprintf("import %s", keyIdArg), Short: "Import a KMS key", Long: "Import a new version to the given KMS key.", - Args: args.NoArgs, + Args: args.SingleArg(keyIdArg, utils.ValidateUUID), Example: examples.Build( examples.NewExample( - `Import a new version for the given KMS key "my-key"`, - `$ stackit beta kms key import --key-ring "my-keyring-id" --key "my-key-id" --wrapped-key "base64-encoded-wrapped-key-material" --wrapping-key-id "my-wrapping-key-id"`), + `Import a new version for the given KMS key "my-key-id"`, + `$ stackit beta kms key import "my-key-id" --key-ring "my-keyring-id" --wrapped-key "base64-encoded-wrapped-key-material" --wrapping-key-id "my-wrapping-key-id"`), ), - RunE: func(cmd *cobra.Command, _ []string) error { + RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() - model, err := parseInput(params.Printer, cmd) + model, err := parseInput(params.Printer, cmd, args) if err != nil { return err } @@ -83,10 +83,6 @@ func NewCmd(params *params.CmdParams) *cobra.Command { // Call API req, _ := buildRequest(ctx, model, apiClient) - if err != nil { - return err - } - keyVersion, err := req.Execute() if err != nil { return fmt.Errorf("import KMS key: %w", err) @@ -99,7 +95,9 @@ func NewCmd(params *params.CmdParams) *cobra.Command { return cmd } -func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { +func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inputModel, error) { + keyId := inputArgs[0] + globalFlags := globalflags.Parse(p, cmd) if globalFlags.ProjectId == "" { return nil, &cliErr.ProjectIdError{} @@ -117,8 +115,8 @@ func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { model := inputModel{ GlobalFlagModel: globalFlags, + KeyId: keyId, KeyRingId: flags.FlagToStringValue(p, cmd, keyRingIdFlag), - KeyId: flags.FlagToStringValue(p, cmd, keyIdFlag), WrappedKey: wrappedKey, WrappingKeyId: flags.FlagToStringPointer(p, cmd, wrappingKeyIdFlag), } @@ -161,7 +159,6 @@ func outputResult(p *print.Printer, outputFormat, keyRingName, keyName string, r return fmt.Errorf("marshal KMS key: %w", err) } p.Outputln(string(details)) - return nil case print.YAMLOutputFormat: details, err := yaml.MarshalWithOptions(resp, yaml.IndentSequence(true), yaml.UseJSONMarshaler()) @@ -169,20 +166,19 @@ func outputResult(p *print.Printer, outputFormat, keyRingName, keyName string, r return fmt.Errorf("marshal KMS key: %w", err) } p.Outputln(string(details)) - return nil default: p.Outputf("Imported a new version for the key %q inside the key ring %q\n", keyName, keyRingName) - return nil } + + return nil } func configureFlags(cmd *cobra.Command) { cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS key ring") - cmd.Flags().Var(flags.UUIDFlag(), keyIdFlag, "ID of the KMS key") cmd.Flags().String(wrappedKeyFlag, "", "The wrapped key material that has to be imported. Encoded in base64") cmd.Flags().Var(flags.UUIDFlag(), wrappingKeyIdFlag, "The unique id of the wrapping key the key material has been wrapped with") - err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, keyIdFlag, wrappedKeyFlag, wrappingKeyIdFlag) + err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, wrappedKeyFlag, wrappingKeyIdFlag) cobra.CheckErr(err) } diff --git a/internal/cmd/beta/kms/key/importKey/importKey_test.go b/internal/cmd/beta/kms/key/importKey/importKey_test.go index 140f382e6..37192e9d1 100644 --- a/internal/cmd/beta/kms/key/importKey/importKey_test.go +++ b/internal/cmd/beta/kms/key/importKey/importKey_test.go @@ -7,7 +7,6 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/uuid" - "github.com/spf13/cobra" "github.com/stackitcloud/stackit-cli/internal/cmd/params" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/print" @@ -30,13 +29,23 @@ var ( testWrappedKey = "SnVzdCBzYXlpbmcgaGV5Oyk=" ) +// Args +func fixtureArgValues(mods ...func(argValues []string)) []string { + argValues := []string{ + testKeyId, + } + for _, mod := range mods { + mod(argValues) + } + return argValues +} + // Flags func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]string { flagValues := map[string]string{ globalflags.ProjectIdFlag: testProjectId, globalflags.RegionFlag: testRegion, keyRingIdFlag: testKeyRingId, - keyIdFlag: testKeyId, wrappedKeyFlag: testWrappedKey, wrappingKeyIdFlag: testWrappingKeyId, } @@ -82,23 +91,33 @@ func fixtureRequest(mods ...func(request *kms.ApiImportKeyRequest)) kms.ApiImpor func TestParseInput(t *testing.T) { tests := []struct { description string + argValues []string flagValues map[string]string isValid bool expectedModel *inputModel }{ { description: "base", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(), isValid: true, expectedModel: fixtureInputModel(), }, + { + description: "no args (keyId)", + argValues: []string{}, + flagValues: fixtureFlagValues(), + isValid: false, + }, { description: "no values provided", + argValues: fixtureArgValues(), flagValues: map[string]string{}, isValid: false, }, { description: "project id missing", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { delete(flagValues, globalflags.ProjectIdFlag) }), @@ -106,6 +125,7 @@ func TestParseInput(t *testing.T) { }, { description: "project id invalid 1", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[globalflags.ProjectIdFlag] = "" }), @@ -113,6 +133,7 @@ func TestParseInput(t *testing.T) { }, { description: "project id invalid 2", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[globalflags.ProjectIdFlag] = "invalid-uuid" }), @@ -120,6 +141,7 @@ func TestParseInput(t *testing.T) { }, { description: "key ring id missing (required)", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { delete(flagValues, keyRingIdFlag) }), @@ -127,6 +149,7 @@ func TestParseInput(t *testing.T) { }, { description: "key ring id invalid 1", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[keyRingIdFlag] = "" }), @@ -134,34 +157,27 @@ func TestParseInput(t *testing.T) { }, { description: "key ring id invalid 2", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[keyRingIdFlag] = "invalid-uuid" }), isValid: false, }, - { - description: "key id missing (required)", - flagValues: fixtureFlagValues(func(flagValues map[string]string) { - delete(flagValues, keyIdFlag) - }), - isValid: false, - }, { description: "key id invalid 1", - flagValues: fixtureFlagValues(func(flagValues map[string]string) { - flagValues[keyIdFlag] = "" - }), - isValid: false, + argValues: []string{""}, + flagValues: fixtureFlagValues(), + isValid: false, }, { description: "key id invalid 2", - flagValues: fixtureFlagValues(func(flagValues map[string]string) { - flagValues[keyIdFlag] = "invalid-uuid" - }), - isValid: false, + argValues: []string{"invalid-key"}, + flagValues: fixtureFlagValues(), + isValid: false, }, { description: "wrapping key id missing (required)", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { delete(flagValues, wrappingKeyIdFlag) }), @@ -169,6 +185,7 @@ func TestParseInput(t *testing.T) { }, { description: "wrapping key id invalid 1", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[wrappingKeyIdFlag] = "" }), @@ -176,6 +193,7 @@ func TestParseInput(t *testing.T) { }, { description: "wrapping key id invalid 2", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[wrappingKeyIdFlag] = "invalid-uuid" }), @@ -183,6 +201,7 @@ func TestParseInput(t *testing.T) { }, { description: "wrapped key missing (required)", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { delete(flagValues, wrappedKeyFlag) }), @@ -190,6 +209,7 @@ func TestParseInput(t *testing.T) { }, { description: "wrapped key invalid 1", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[wrappedKeyFlag] = "" }), @@ -197,6 +217,7 @@ func TestParseInput(t *testing.T) { }, { description: "wrapped key invalid 2 - not base64", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[wrappedKeyFlag] = "Not Base 64" }), @@ -206,13 +227,20 @@ func TestParseInput(t *testing.T) { for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { - cmd := &cobra.Command{} + p := print.NewPrinter() + cmd := NewCmd(¶ms.CmdParams{Printer: p}) err := globalflags.Configure(cmd.Flags()) if err != nil { t.Fatalf("configure global flags: %v", err) } - configureFlags(cmd) + err = cmd.ValidateArgs(tt.argValues) + if err != nil { + if !tt.isValid { + return + } + t.Fatalf("error validating args: %v", err) + } for flag, value := range tt.flagValues { err := cmd.Flags().Set(flag, value) @@ -232,8 +260,7 @@ func TestParseInput(t *testing.T) { t.Fatalf("error validating flags: %v", err) } - p := print.NewPrinter() - model, err := parseInput(p, cmd) + model, err := parseInput(p, cmd, tt.argValues) if err != nil { if !tt.isValid { return diff --git a/internal/cmd/beta/kms/key/list/list.go b/internal/cmd/beta/kms/key/list/list.go index c1f4d49ca..d1f3a841f 100644 --- a/internal/cmd/beta/kms/key/list/list.go +++ b/internal/cmd/beta/kms/key/list/list.go @@ -11,6 +11,7 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/args" "github.com/stackitcloud/stackit-cli/internal/pkg/errors" "github.com/stackitcloud/stackit-cli/internal/pkg/examples" + "github.com/stackitcloud/stackit-cli/internal/pkg/flags" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/print" "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/client" @@ -20,7 +21,7 @@ import ( ) const ( - keyRingIdArg = "KEYRING_ID" + keyRingIdFlag = "key-ring-id" ) type inputModel struct { @@ -30,21 +31,21 @@ type inputModel struct { func NewCmd(params *params.CmdParams) *cobra.Command { cmd := &cobra.Command{ - Use: fmt.Sprintf("list %s", keyRingIdArg), + Use: "list", Short: "List all KMS keys", Long: "List all KMS keys inside a key ring.", - Args: args.SingleArg(keyRingIdArg, utils.ValidateUUID), + Args: args.NoArgs, Example: examples.Build( examples.NewExample( - `List all KMS keys for the key ring "xxx"`, - "$ stackit beta kms key list xxx"), + `List all KMS keys for the key ring "my-key-ring-id"`, + `$ stackit beta kms key list --key-ring "my-key-ring-id"`), examples.NewExample( `List all KMS keys in JSON format`, - "$ stackit beta kms key list xxx --output-format json"), + `$ stackit beta kms key list --key-ring "my-key-ring-id" --output-format json`), ), - RunE: func(cmd *cobra.Command, args []string) error { + RunE: func(cmd *cobra.Command, _ []string) error { ctx := context.Background() - model, err := parseInput(params.Printer, cmd, args) + model, err := parseInput(params.Printer, cmd) if err != nil { return err } @@ -66,12 +67,11 @@ func NewCmd(params *params.CmdParams) *cobra.Command { }, } + configureFlags(cmd) return cmd } -func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inputModel, error) { - keyRingId := inputArgs[0] - +func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { globalFlags := globalflags.Parse(p, cmd) if globalFlags.ProjectId == "" { return nil, &errors.ProjectIdError{} @@ -79,7 +79,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu model := inputModel{ GlobalFlagModel: globalFlags, - KeyRingId: keyRingId, + KeyRingId: flags.FlagToStringValue(p, cmd, keyRingIdFlag), } if p.IsVerbosityDebug() { @@ -99,6 +99,12 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClie return req } +func configureFlags(cmd *cobra.Command) { + cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS Key Ring where the Key is stored") + err := flags.MarkFlagsRequired(cmd, keyRingIdFlag) + cobra.CheckErr(err) +} + func outputResult(p *print.Printer, outputFormat, projectId, keyRingId string, keys []kms.Key) error { switch outputFormat { case print.JSONOutputFormat: @@ -108,7 +114,6 @@ func outputResult(p *print.Printer, outputFormat, projectId, keyRingId string, k } p.Outputln(string(details)) - return nil case print.YAMLOutputFormat: details, err := yaml.MarshalWithOptions(keys, yaml.IndentSequence(true), yaml.UseJSONMarshaler()) if err != nil { @@ -116,7 +121,6 @@ func outputResult(p *print.Printer, outputFormat, projectId, keyRingId string, k } p.Outputln(string(details)) - return nil default: if len(keys) == 0 { p.Outputf("No keys found for project %q under the key ring %q\n", projectId, keyRingId) @@ -140,7 +144,6 @@ func outputResult(p *print.Printer, outputFormat, projectId, keyRingId string, k if err != nil { return fmt.Errorf("render table: %w", err) } - - return nil } + return nil } diff --git a/internal/cmd/beta/kms/key/list/list_test.go b/internal/cmd/beta/kms/key/list/list_test.go index 65e4a11e9..49e1aa000 100644 --- a/internal/cmd/beta/kms/key/list/list_test.go +++ b/internal/cmd/beta/kms/key/list/list_test.go @@ -7,6 +7,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/uuid" + "github.com/spf13/cobra" "github.com/stackitcloud/stackit-cli/internal/cmd/params" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/print" @@ -26,22 +27,12 @@ var ( testKeyRingId = uuid.NewString() ) -// Args -func fixtureArgValues(mods ...func(argValues []string)) []string { - argValues := []string{ - testKeyRingId, - } - for _, mod := range mods { - mod(argValues) - } - return argValues -} - // Flags func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]string { flagValues := map[string]string{ globalflags.ProjectIdFlag: testProjectId, globalflags.RegionFlag: testRegion, + keyRingIdFlag: testKeyRingId, } for _, mod := range mods { mod(flagValues) @@ -77,35 +68,39 @@ func fixtureRequest(mods ...func(request *kms.ApiListKeysRequest)) kms.ApiListKe func TestParseInput(t *testing.T) { tests := []struct { description string - argValues []string flagValues map[string]string isValid bool expectedModel *inputModel }{ { description: "base", - argValues: fixtureArgValues(), flagValues: fixtureFlagValues(), isValid: true, expectedModel: fixtureInputModel(), }, { - description: "no args (keyRingId)", - argValues: []string{}, - flagValues: fixtureFlagValues(), - isValid: false, + description: "missing keyRingId", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, keyRingIdFlag) + }), + isValid: false, }, { - description: "invalid keyRingId", - argValues: fixtureArgValues(func(argValues []string) { - argValues[0] = "Not an uuid" + description: "invalid keyRingId 1", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyRingIdFlag] = "" }), - flagValues: fixtureFlagValues(), - isValid: false, + isValid: false, + }, + { + description: "invalid keyRingId 2", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyRingIdFlag] = "Not a valid uuid" + }), + isValid: false, }, { description: "project id missing", - argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { delete(flagValues, globalflags.ProjectIdFlag) }), @@ -113,7 +108,6 @@ func TestParseInput(t *testing.T) { }, { description: "project id invalid 1", - argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[globalflags.ProjectIdFlag] = "" }), @@ -121,7 +115,6 @@ func TestParseInput(t *testing.T) { }, { description: "project id invalid 2", - argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[globalflags.ProjectIdFlag] = "invalid-uuid" }), @@ -131,13 +124,13 @@ func TestParseInput(t *testing.T) { for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { - p := print.NewPrinter() - cmd := NewCmd(¶ms.CmdParams{Printer: p}) + cmd := &cobra.Command{} err := globalflags.Configure(cmd.Flags()) if err != nil { t.Fatalf("configure global flags: %v", err) } + configureFlags(cmd) for flag, value := range tt.flagValues { err := cmd.Flags().Set(flag, value) if err != nil { @@ -148,14 +141,6 @@ func TestParseInput(t *testing.T) { } } - 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 { @@ -164,7 +149,8 @@ func TestParseInput(t *testing.T) { t.Fatalf("error validating flags: %v", err) } - model, err := parseInput(p, cmd, tt.argValues) + p := print.NewPrinter() + model, err := parseInput(p, cmd) if err != nil { if !tt.isValid { return diff --git a/internal/cmd/beta/kms/key/restore/restore.go b/internal/cmd/beta/kms/key/restore/restore.go index 10465df44..236bda622 100644 --- a/internal/cmd/beta/kms/key/restore/restore.go +++ b/internal/cmd/beta/kms/key/restore/restore.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" + "github.com/goccy/go-yaml" "github.com/spf13/cobra" "github.com/stackitcloud/stackit-cli/internal/cmd/params" "github.com/stackitcloud/stackit-cli/internal/pkg/args" @@ -14,37 +15,38 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/print" kmsUtils "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/utils" - "gopkg.in/yaml.v2" + "github.com/stackitcloud/stackit-cli/internal/pkg/utils" "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/client" "github.com/stackitcloud/stackit-sdk-go/services/kms" ) const ( - keyRingIdFlag = "key-ring" - keyIdFlag = "key" + keyIdArg = "KEY_ID" + + keyRingIdFlag = "key-ring-id" ) type inputModel struct { *globalflags.GlobalFlagModel - KeyRingId string KeyId string + KeyRingId string } func NewCmd(params *params.CmdParams) *cobra.Command { cmd := &cobra.Command{ - Use: "restore", + Use: fmt.Sprintf("restore %s", keyIdArg), Short: "Restore a key", Long: "Restores the given key from being deleted.", - Args: args.NoArgs, + Args: args.SingleArg(keyIdArg, utils.ValidateUUID), Example: examples.Build( examples.NewExample( `Restore a KMS key "my-key-id" inside the key ring "my-key-ring-id" that was scheduled for deletion.`, - `$ stackit beta kms keyring restore --key-ring "my-key-ring-id" --key "my-key-id"`), + `$ stackit beta kms keyring restore "my-key-id" --key-ring "my-key-ring-id"`), ), - RunE: func(cmd *cobra.Command, _ []string) error { + RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() - model, err := parseInput(params.Printer, cmd) + model, err := parseInput(params.Printer, cmd, args) if err != nil { return err } @@ -76,7 +78,13 @@ func NewCmd(params *params.CmdParams) *cobra.Command { return fmt.Errorf("restore KMS key: %w", err) } - return outputResult(params.Printer, model.OutputFormat, model.KeyId, keyName) + // Grab the key after the restore was applied to display the new state to the user. + resp, err := apiClient.GetKeyExecute(ctx, model.ProjectId, model.Region, model.KeyRingId, model.KeyId) + if err != nil { + params.Printer.Debug(print.ErrorLevel, "get key: %v", err) + } + + return outputResult(params.Printer, model.OutputFormat, resp) }, } @@ -84,7 +92,9 @@ func NewCmd(params *params.CmdParams) *cobra.Command { return cmd } -func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { +func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inputModel, error) { + keyId := inputArgs[0] + globalFlags := globalflags.Parse(p, cmd) if globalFlags.ProjectId == "" { return nil, &errors.ProjectIdError{} @@ -93,7 +103,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { model := inputModel{ GlobalFlagModel: globalFlags, KeyRingId: flags.FlagToStringValue(p, cmd, keyRingIdFlag), - KeyId: flags.FlagToStringValue(p, cmd, keyIdFlag), + KeyId: keyId, } if p.IsVerbosityDebug() { @@ -115,49 +125,31 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClie func configureFlags(cmd *cobra.Command) { cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS Key Ring where the Key is stored") - cmd.Flags().Var(flags.UUIDFlag(), keyIdFlag, "ID of the actual Key") - err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, keyIdFlag) + err := flags.MarkFlagsRequired(cmd, keyRingIdFlag) cobra.CheckErr(err) } -func outputResult(p *print.Printer, outputFormat, keyId, keyName string) error { +func outputResult(p *print.Printer, outputFormat string, resp *kms.Key) error { + if resp == nil { + return fmt.Errorf("response from 'GetKeyExecute()' is nil") + } + switch outputFormat { case print.JSONOutputFormat: - details := struct { - KeyId string `json:"keyId"` - KeyName string `json:"keyName"` - Status string `json:"status"` - }{ - KeyId: keyId, - KeyName: keyName, - Status: "key restored", - } - b, err := json.MarshalIndent(details, "", " ") + details, err := json.MarshalIndent(resp, "", " ") if err != nil { return fmt.Errorf("marshal output to JSON: %w", err) } - p.Outputln(string(b)) - return nil - + p.Outputln(string(details)) case print.YAMLOutputFormat: - details := struct { - KeyId string `yaml:"keyId"` - KeyName string `yaml:"keyName"` - Status string `yaml:"status"` - }{ - KeyId: keyId, - KeyName: keyName, - Status: "key restored", - } - b, err := yaml.Marshal(details) + details, err := yaml.MarshalWithOptions(resp, yaml.IndentSequence(true), yaml.UseJSONMarshaler()) if err != nil { return fmt.Errorf("marshal output to YAML: %w", err) } - p.Outputln(string(b)) - return nil + p.Outputln(string(details)) default: - p.Outputf("Successfully restored KMS key %q\n", keyName) - return nil + p.Outputf("Successfully restored KMS key '%s'\n", utils.PtrString(resp.DisplayName)) } + return nil } diff --git a/internal/cmd/beta/kms/key/restore/restore_test.go b/internal/cmd/beta/kms/key/restore/restore_test.go index ef654faf6..b9af8a63a 100644 --- a/internal/cmd/beta/kms/key/restore/restore_test.go +++ b/internal/cmd/beta/kms/key/restore/restore_test.go @@ -7,7 +7,6 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/uuid" - "github.com/spf13/cobra" "github.com/stackitcloud/stackit-cli/internal/cmd/params" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/print" @@ -28,13 +27,23 @@ var ( testKeyId = uuid.NewString() ) +// Args +func fixtureArgValues(mods ...func(argValues []string)) []string { + argValues := []string{ + testKeyId, + } + for _, mod := range mods { + mod(argValues) + } + return argValues +} + // Flags func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]string { flagValues := map[string]string{ globalflags.ProjectIdFlag: testProjectId, globalflags.RegionFlag: testRegion, keyRingIdFlag: testKeyRingId, - keyIdFlag: testKeyId, } for _, mod := range mods { mod(flagValues) @@ -71,23 +80,33 @@ func fixtureRequest(mods ...func(request *kms.ApiRestoreKeyRequest)) kms.ApiRest func TestParseInput(t *testing.T) { tests := []struct { description string + argValues []string flagValues map[string]string isValid bool expectedModel *inputModel }{ { description: "base", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(), expectedModel: fixtureInputModel(), isValid: true, }, + { + description: "no args (keyId)", + argValues: []string{}, + flagValues: fixtureFlagValues(), + isValid: false, + }, { description: "no values", + argValues: fixtureArgValues(), flagValues: map[string]string{}, isValid: false, }, { description: "project id missing", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { delete(flagValues, globalflags.ProjectIdFlag) }), @@ -95,6 +114,7 @@ func TestParseInput(t *testing.T) { }, { description: "project id invalid 1", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[globalflags.ProjectIdFlag] = "" }), @@ -102,6 +122,7 @@ func TestParseInput(t *testing.T) { }, { description: "project id invalid 2", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[globalflags.ProjectIdFlag] = "invalid-uuid" }), @@ -109,6 +130,7 @@ func TestParseInput(t *testing.T) { }, { description: "key ring id missing", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { delete(flagValues, keyRingIdFlag) }), @@ -116,6 +138,7 @@ func TestParseInput(t *testing.T) { }, { description: "key ring id invalid 1", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[keyRingIdFlag] = "" }), @@ -123,43 +146,42 @@ func TestParseInput(t *testing.T) { }, { description: "key ring id invalid 2", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[keyRingIdFlag] = "invalid-uuid" }), isValid: false, }, - { - description: "key id missing", - flagValues: fixtureFlagValues(func(flagValues map[string]string) { - delete(flagValues, keyIdFlag) - }), - isValid: false, - }, { description: "key id invalid 1", - flagValues: fixtureFlagValues(func(flagValues map[string]string) { - flagValues[keyIdFlag] = "" - }), - isValid: false, + argValues: []string{""}, + flagValues: fixtureFlagValues(), + isValid: false, }, { description: "key id invalid 2", - flagValues: fixtureFlagValues(func(flagValues map[string]string) { - flagValues[keyIdFlag] = "invalid-uuid" - }), - isValid: false, + argValues: []string{"invalid-uuid"}, + flagValues: fixtureFlagValues(), + isValid: false, }, } for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { - cmd := &cobra.Command{} + p := print.NewPrinter() + cmd := NewCmd(¶ms.CmdParams{Printer: p}) err := globalflags.Configure(cmd.Flags()) if err != nil { t.Fatalf("configure global flags: %v", err) } - configureFlags(cmd) + err = cmd.ValidateArgs(tt.argValues) + if err != nil { + if !tt.isValid { + return + } + t.Fatalf("error validating args: %v", err) + } for flag, value := range tt.flagValues { err := cmd.Flags().Set(flag, value) @@ -179,8 +201,7 @@ func TestParseInput(t *testing.T) { t.Fatalf("error validating flags: %v", err) } - p := print.NewPrinter() - model, err := parseInput(p, cmd) + model, err := parseInput(p, cmd, tt.argValues) if err != nil { if !tt.isValid { return @@ -232,27 +253,23 @@ func TestOutputResult(t *testing.T) { description string wantErr bool outputFormat string - keyId string - keyName string + resp *kms.Key }{ { description: "default output", - keyId: uuid.NewString(), - keyName: uuid.NewString(), + resp: &kms.Key{}, wantErr: false, }, { description: "json output", outputFormat: print.JSONOutputFormat, - keyId: uuid.NewString(), - keyName: uuid.NewString(), + resp: &kms.Key{}, wantErr: false, }, { description: "yaml output", outputFormat: print.YAMLOutputFormat, - keyId: uuid.NewString(), - keyName: uuid.NewString(), + resp: &kms.Key{}, wantErr: false, }, } @@ -261,7 +278,7 @@ func TestOutputResult(t *testing.T) { p.Cmd = NewCmd(¶ms.CmdParams{Printer: p}) for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { - err := outputResult(p, tt.outputFormat, tt.keyId, tt.keyName) + err := outputResult(p, tt.outputFormat, tt.resp) if (err != nil) != tt.wantErr { t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr) } diff --git a/internal/cmd/beta/kms/key/rotate/rotate.go b/internal/cmd/beta/kms/key/rotate/rotate.go index e38c07ae3..71f2e3449 100644 --- a/internal/cmd/beta/kms/key/rotate/rotate.go +++ b/internal/cmd/beta/kms/key/rotate/rotate.go @@ -22,30 +22,31 @@ import ( ) const ( - keyRingIdFlag = "key-ring" - keyIdFlag = "key" + keyIdArg = "KEY_ID" + + keyRingIdFlag = "key-ring-id" ) type inputModel struct { *globalflags.GlobalFlagModel - KeyRingId string KeyId string + KeyRingId string } func NewCmd(params *params.CmdParams) *cobra.Command { cmd := &cobra.Command{ - Use: "rotate", + Use: fmt.Sprintf("rotate %s", keyIdArg), Short: "Rotate a key", Long: "Rotates the given key.", - Args: args.NoArgs, + Args: args.SingleArg(keyIdArg, utils.ValidateUUID), Example: examples.Build( examples.NewExample( `Rotate a KMS key "my-key-id" and increase it's version inside the key ring "my-key-ring-id".`, - `$ stackit beta kms key rotate --key-ring "my-key-ring-id" --key "my-key-id"`), + `$ stackit beta kms key rotate "my-key-id" --key-ring "my-key-ring-id"`), ), - RunE: func(cmd *cobra.Command, _ []string) error { + RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() - model, err := parseInput(params.Printer, cmd) + model, err := parseInput(params.Printer, cmd, args) if err != nil { return err } @@ -85,7 +86,9 @@ func NewCmd(params *params.CmdParams) *cobra.Command { return cmd } -func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { +func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inputModel, error) { + keyId := inputArgs[0] + globalFlags := globalflags.Parse(p, cmd) if globalFlags.ProjectId == "" { return nil, &errors.ProjectIdError{} @@ -94,7 +97,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { model := inputModel{ GlobalFlagModel: globalFlags, KeyRingId: flags.FlagToStringValue(p, cmd, keyRingIdFlag), - KeyId: flags.FlagToStringValue(p, cmd, keyIdFlag), + KeyId: keyId, } if p.IsVerbosityDebug() { @@ -116,8 +119,7 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClie func configureFlags(cmd *cobra.Command) { cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS key Ring where the key is stored") - cmd.Flags().Var(flags.UUIDFlag(), keyIdFlag, "ID of the actual key") - err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, keyIdFlag) + err := flags.MarkFlagsRequired(cmd, keyRingIdFlag) cobra.CheckErr(err) } @@ -133,7 +135,6 @@ func outputResult(p *print.Printer, outputFormat string, resp *kms.Version) erro return fmt.Errorf("marshal KMS key version: %w", err) } p.Outputln(string(details)) - return nil case print.YAMLOutputFormat: details, err := yaml.MarshalWithOptions(resp, yaml.IndentSequence(true), yaml.UseJSONMarshaler()) @@ -141,10 +142,10 @@ func outputResult(p *print.Printer, outputFormat string, resp *kms.Version) erro return fmt.Errorf("marshal KMS key version: %w", err) } p.Outputln(string(details)) - return nil default: p.Outputf("Rotated key %s\n", utils.PtrString(resp.KeyId)) - return nil } + + return nil } diff --git a/internal/cmd/beta/kms/key/rotate/rotate_test.go b/internal/cmd/beta/kms/key/rotate/rotate_test.go index b7e8430a9..28d84295e 100644 --- a/internal/cmd/beta/kms/key/rotate/rotate_test.go +++ b/internal/cmd/beta/kms/key/rotate/rotate_test.go @@ -7,7 +7,6 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/uuid" - "github.com/spf13/cobra" "github.com/stackitcloud/stackit-cli/internal/cmd/params" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/print" @@ -28,13 +27,23 @@ var ( testKeyId = uuid.NewString() ) +// Args +func fixtureArgValues(mods ...func(argValues []string)) []string { + argValues := []string{ + testKeyId, + } + for _, mod := range mods { + mod(argValues) + } + return argValues +} + // Flags func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]string { flagValues := map[string]string{ globalflags.ProjectIdFlag: testProjectId, globalflags.RegionFlag: testRegion, keyRingIdFlag: testKeyRingId, - keyIdFlag: testKeyId, } for _, mod := range mods { mod(flagValues) @@ -71,23 +80,33 @@ func fixtureRequest(mods ...func(request *kms.ApiRotateKeyRequest)) kms.ApiRotat func TestParseInput(t *testing.T) { tests := []struct { description string + argValues []string flagValues map[string]string isValid bool expectedModel *inputModel }{ { description: "base", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(), expectedModel: fixtureInputModel(), isValid: true, }, + { + description: "no args (keyId)", + argValues: []string{}, + flagValues: fixtureFlagValues(), + isValid: false, + }, { description: "no values", + argValues: fixtureArgValues(), flagValues: map[string]string{}, isValid: false, }, { description: "project id missing", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { delete(flagValues, globalflags.ProjectIdFlag) }), @@ -95,6 +114,7 @@ func TestParseInput(t *testing.T) { }, { description: "project id invalid 1", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[globalflags.ProjectIdFlag] = "" }), @@ -102,6 +122,7 @@ func TestParseInput(t *testing.T) { }, { description: "project id invalid 2", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[globalflags.ProjectIdFlag] = "invalid-uuid" }), @@ -109,6 +130,7 @@ func TestParseInput(t *testing.T) { }, { description: "key ring id missing", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { delete(flagValues, keyRingIdFlag) }), @@ -116,6 +138,7 @@ func TestParseInput(t *testing.T) { }, { description: "key ring id invalid 1", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[keyRingIdFlag] = "" }), @@ -123,43 +146,42 @@ func TestParseInput(t *testing.T) { }, { description: "key ring id invalid 2", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[keyRingIdFlag] = "invalid-uuid" }), isValid: false, }, - { - description: "key id missing", - flagValues: fixtureFlagValues(func(flagValues map[string]string) { - delete(flagValues, keyIdFlag) - }), - isValid: false, - }, { description: "key id invalid 1", - flagValues: fixtureFlagValues(func(flagValues map[string]string) { - flagValues[keyIdFlag] = "" - }), - isValid: false, + argValues: []string{""}, + flagValues: fixtureFlagValues(), + isValid: false, }, { description: "key id invalid 2", - flagValues: fixtureFlagValues(func(flagValues map[string]string) { - flagValues[keyIdFlag] = "invalid-uuid" - }), - isValid: false, + argValues: []string{"invalid-uuid"}, + flagValues: fixtureFlagValues(), + isValid: false, }, } for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { - cmd := &cobra.Command{} + p := print.NewPrinter() + cmd := NewCmd(¶ms.CmdParams{Printer: p}) err := globalflags.Configure(cmd.Flags()) if err != nil { t.Fatalf("configure global flags: %v", err) } - configureFlags(cmd) + err = cmd.ValidateArgs(tt.argValues) + if err != nil { + if !tt.isValid { + return + } + t.Fatalf("error validating args: %v", err) + } for flag, value := range tt.flagValues { err := cmd.Flags().Set(flag, value) @@ -179,8 +201,7 @@ func TestParseInput(t *testing.T) { t.Fatalf("error validating flags: %v", err) } - p := print.NewPrinter() - model, err := parseInput(p, cmd) + model, err := parseInput(p, cmd, tt.argValues) if err != nil { if !tt.isValid { return diff --git a/internal/cmd/beta/kms/keyring/create/create.go b/internal/cmd/beta/kms/keyring/create/create.go index b5ff5a5b7..93fb244ba 100644 --- a/internal/cmd/beta/kms/keyring/create/create.go +++ b/internal/cmd/beta/kms/keyring/create/create.go @@ -168,7 +168,6 @@ func outputResult(p *print.Printer, outputFormat, projectLabel string, resp *kms return fmt.Errorf("marshal KMS key ring: %w", err) } p.Outputln(string(details)) - return nil case print.YAMLOutputFormat: details, err := yaml.MarshalWithOptions(resp, yaml.IndentSequence(true), yaml.UseJSONMarshaler()) @@ -176,12 +175,11 @@ func outputResult(p *print.Printer, outputFormat, projectLabel string, resp *kms return fmt.Errorf("marshal KMS key ring: %w", err) } p.Outputln(string(details)) - return nil default: - p.Outputf("Created instance for project %q. Instance ID: %s\n", projectLabel, utils.PtrString(resp.Id)) - return nil + p.Outputf("Created instance for project %q. Key ring ID: %s\n", projectLabel, utils.PtrString(resp.Id)) } + return nil } func configureFlags(cmd *cobra.Command) { diff --git a/internal/cmd/beta/kms/keyring/delete/delete.go b/internal/cmd/beta/kms/keyring/delete/delete.go index 34f542221..e089fc8c4 100644 --- a/internal/cmd/beta/kms/keyring/delete/delete.go +++ b/internal/cmd/beta/kms/keyring/delete/delete.go @@ -37,8 +37,8 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Args: args.SingleArg(keyRingIdArg, utils.ValidateUUID), Example: examples.Build( examples.NewExample( - `Delete a KMS key ring with ID "xxx"`, - "$ stackit beta kms keyring delete xxx"), + `Delete a KMS key ring with ID "my-key-ring-id"`, + `$ stackit beta kms keyring delete "my-key-ring-id"`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() @@ -76,7 +76,12 @@ func NewCmd(params *params.CmdParams) *cobra.Command { // Wait for async operation not relevant. Key ring deletion is synchronous. - return outputResult(params.Printer, model.OutputFormat, keyRingLabel) + // Get the key ring so it can be outputted in the state it is after the deletion. + resp, err := apiClient.GetKeyRingExecute(ctx, model.ProjectId, model.Region, model.KeyRingId) + if err != nil { + params.Printer.Debug(print.ErrorLevel, "get KMS Key Ring: %w", err) + } + return outputResult(params.Printer, model.OutputFormat, resp) }, } return cmd @@ -112,40 +117,27 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClie return req } -func outputResult(p *print.Printer, outputFormat, keyRingLabel string) error { +func outputResult(p *print.Printer, outputFormat string, resp *kms.KeyRing) error { + if resp == nil { + return fmt.Errorf("response from 'GetKeyExecute()' is nil") + } + switch outputFormat { case print.JSONOutputFormat: - details := struct { - KeyRingLabel string `json:"keyRingLabel"` - Status string `json:"status"` - }{ - KeyRingLabel: keyRingLabel, - Status: "Key ring deleted.", - } - b, err := json.MarshalIndent(details, "", " ") + details, err := json.MarshalIndent(resp, "", " ") if err != nil { return fmt.Errorf("marshal output to JSON: %w", err) } - p.Outputln(string(b)) - return nil - + p.Outputln(string(details)) case print.YAMLOutputFormat: - details := struct { - KeyRingLabel string `yaml:"keyRingLabel"` - Status string `yaml:"status"` - }{ - KeyRingLabel: keyRingLabel, - Status: "Key ring deleted.", - } - b, err := yaml.Marshal(details) + details, err := yaml.MarshalWithOptions(resp, yaml.IndentSequence(true), yaml.UseJSONMarshaler()) if err != nil { return fmt.Errorf("marshal output to YAML: %w", err) } - p.Outputln(string(b)) - return nil + p.Outputln(string(details)) default: - p.Outputf("Deleted key ring: %s\n", keyRingLabel) - return nil + p.Outputf("Deleted key ring: %s\n", utils.PtrString(resp.DisplayName)) } + return nil } diff --git a/internal/cmd/beta/kms/keyring/delete/delete_test.go b/internal/cmd/beta/kms/keyring/delete/delete_test.go index c3b400ea9..c8b4a6e3b 100644 --- a/internal/cmd/beta/kms/keyring/delete/delete_test.go +++ b/internal/cmd/beta/kms/keyring/delete/delete_test.go @@ -216,23 +216,23 @@ func TestOutputResult(t *testing.T) { description string wantErr bool outputFormat string - keyRingLabel string + resp *kms.KeyRing }{ { - description: "default output", - keyRingLabel: "yourKeyRing", - wantErr: false, + description: "default output", + resp: &kms.KeyRing{}, + wantErr: false, }, { description: "json output", outputFormat: print.JSONOutputFormat, - keyRingLabel: "yourKeyRing", + resp: &kms.KeyRing{}, wantErr: false, }, { description: "yaml output", outputFormat: print.YAMLOutputFormat, - keyRingLabel: "yourKeyRing", + resp: &kms.KeyRing{}, wantErr: false, }, } @@ -241,7 +241,7 @@ func TestOutputResult(t *testing.T) { p.Cmd = NewCmd(¶ms.CmdParams{Printer: p}) for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { - err := outputResult(p, tt.outputFormat, tt.keyRingLabel) + err := outputResult(p, tt.outputFormat, tt.resp) if (err != nil) != tt.wantErr { t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr) } diff --git a/internal/cmd/beta/kms/keyring/list/list.go b/internal/cmd/beta/kms/keyring/list/list.go index ea8d96b6b..531c826b0 100644 --- a/internal/cmd/beta/kms/keyring/list/list.go +++ b/internal/cmd/beta/kms/keyring/list/list.go @@ -100,7 +100,6 @@ func outputResult(p *print.Printer, outputFormat, projectId string, keyRings []k } p.Outputln(string(details)) - return nil case print.YAMLOutputFormat: details, err := yaml.MarshalWithOptions(keyRings, yaml.IndentSequence(true), yaml.UseJSONMarshaler()) if err != nil { @@ -108,7 +107,6 @@ func outputResult(p *print.Printer, outputFormat, projectId string, keyRings []k } p.Outputln(string(details)) - return nil default: if len(keyRings) == 0 { p.Outputf("No key rings found for project %q\n", projectId) @@ -131,7 +129,7 @@ func outputResult(p *print.Printer, outputFormat, projectId string, keyRings []k if err != nil { return fmt.Errorf("render table: %w", err) } - - return nil } + + return nil } diff --git a/internal/cmd/beta/kms/version/destroy/destroy.go b/internal/cmd/beta/kms/version/destroy/destroy.go index e20d11df7..0d21821b6 100644 --- a/internal/cmd/beta/kms/version/destroy/destroy.go +++ b/internal/cmd/beta/kms/version/destroy/destroy.go @@ -4,7 +4,9 @@ import ( "context" "encoding/json" "fmt" + "strconv" + "github.com/goccy/go-yaml" "github.com/spf13/cobra" "github.com/stackitcloud/stackit-cli/internal/cmd/params" "github.com/stackitcloud/stackit-cli/internal/pkg/args" @@ -14,38 +16,38 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/print" "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/client" - kmsUtils "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/utils" + "github.com/stackitcloud/stackit-cli/internal/pkg/utils" "github.com/stackitcloud/stackit-sdk-go/services/kms" - "gopkg.in/yaml.v2" ) const ( - keyRingIdFlag = "key-ring" - keyIdFlag = "key" - versionNumberFlag = "version" + versionNumberArg = "VERSION_NUMBER" + + keyRingIdFlag = "key-ring-id" + keyIdFlag = "key-id" ) type inputModel struct { *globalflags.GlobalFlagModel KeyRingId string KeyId string - VersionNumber *int64 + VersionNumber int64 } func NewCmd(params *params.CmdParams) *cobra.Command { cmd := &cobra.Command{ - Use: "destroy", + Use: fmt.Sprintf("destroy %s", versionNumberArg), Short: "Destroy a key version", Long: "Removes the key material of a version.", - Args: args.NoArgs, + Args: args.SingleArg(versionNumberArg, nil), Example: examples.Build( examples.NewExample( - `Destroy key version "0" for the key "my-key-id" inside the key ring "my-key-ring-id"`, - `$ stackit beta kms version destroy --key "my-key-id" --key-ring "my-key-ring-id" --version 0`), + `Destroy key version "42" for the key "my-key-id" inside the key ring "my-key-ring-id"`, + `$ stackit beta kms version destroy 42 --key "my-key-id" --key-ring "my-key-ring-id"`), ), - RunE: func(cmd *cobra.Command, _ []string) error { + RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() - model, err := parseInput(params.Printer, cmd) + model, err := parseInput(params.Printer, cmd, args) if err != nil { return err } @@ -56,11 +58,6 @@ func NewCmd(params *params.CmdParams) *cobra.Command { return err } - keyName, err := kmsUtils.GetKeyName(ctx, apiClient, model.ProjectId, model.Region, model.KeyRingId, model.KeyId) - if err != nil { - params.Printer.Debug(print.ErrorLevel, "get key name: %v", err) - keyName = model.KeyId - } // This operation can be undone. Don't ask for confirmation! // Call API @@ -70,7 +67,13 @@ func NewCmd(params *params.CmdParams) *cobra.Command { return fmt.Errorf("destroy key Version: %w", err) } - return outputResult(params.Printer, model.OutputFormat, *model.VersionNumber, model.KeyId, keyName) + // Get the key version in its state afterwards + resp, err := apiClient.GetVersionExecute(ctx, model.ProjectId, model.Region, model.KeyRingId, model.KeyId, model.VersionNumber) + if err != nil { + params.Printer.Debug(print.ErrorLevel, "get key version: %v", err) + } + + return outputResult(params.Printer, model.OutputFormat, resp) }, } @@ -78,7 +81,16 @@ func NewCmd(params *params.CmdParams) *cobra.Command { return cmd } -func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { +func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inputModel, error) { + versionStr := inputArgs[0] + versionNumber, err := strconv.ParseInt(versionStr, 10, 64) + if err != nil || versionNumber < 0 { + return nil, &errors.ArgValidationError{ + Arg: versionNumberArg, + Details: fmt.Sprintf("invalid value %q: must be a positive integer", versionStr), + } + } + globalFlags := globalflags.Parse(p, cmd) if globalFlags.ProjectId == "" { return nil, &errors.ProjectIdError{} @@ -88,7 +100,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { GlobalFlagModel: globalFlags, KeyRingId: flags.FlagToStringValue(p, cmd, keyRingIdFlag), KeyId: flags.FlagToStringValue(p, cmd, keyIdFlag), - VersionNumber: flags.FlagToInt64Pointer(p, cmd, versionNumberFlag), + VersionNumber: versionNumber, } if p.IsVerbosityDebug() { @@ -104,60 +116,40 @@ func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { } func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClient) kms.ApiDestroyVersionRequest { - return apiClient.DestroyVersion(ctx, model.ProjectId, model.Region, model.KeyRingId, model.KeyId, *model.VersionNumber) + return apiClient.DestroyVersion(ctx, model.ProjectId, model.Region, model.KeyRingId, model.KeyId, model.VersionNumber) } func configureFlags(cmd *cobra.Command) { cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS key ring") cmd.Flags().Var(flags.UUIDFlag(), keyIdFlag, "ID of the key") - cmd.Flags().Int64(versionNumberFlag, 0, "Version number of the key") - err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, keyIdFlag, versionNumberFlag) + err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, keyIdFlag) cobra.CheckErr(err) } -func outputResult(p *print.Printer, outputFormat string, versionNumber int64, keyId, keyName string) error { +func outputResult(p *print.Printer, outputFormat string, resp *kms.Version) error { + if resp == nil { + return fmt.Errorf("response is nil") + } + switch outputFormat { case print.JSONOutputFormat: - details := struct { - KeyId string `json:"keyId"` - KeyName string `json:"keyName"` - VersionNumber int64 `json:"versionNumber"` - Status string `json:"status"` - }{ - KeyId: keyId, - KeyName: keyName, - VersionNumber: versionNumber, - Status: fmt.Sprintf("Destroyed version %d of key '%s'.", versionNumber, keyName), - } - b, err := json.MarshalIndent(details, "", " ") + details, err := json.MarshalIndent(resp, "", " ") if err != nil { - return fmt.Errorf("marshal output to JSON: %w", err) + return fmt.Errorf("marshal KMS key: %w", err) } - p.Outputln(string(b)) - return nil + p.Outputln(string(details)) case print.YAMLOutputFormat: - details := struct { - KeyId string `yaml:"keyId"` - KeyName string `yaml:"keyName"` - VersionNumber int64 `yaml:"versionNumber"` - Status string `yaml:"status"` - }{ - KeyId: keyId, - KeyName: keyName, - VersionNumber: versionNumber, - Status: fmt.Sprintf("Destroyed version %d of key '%s'.", versionNumber, keyName), - } - b, err := yaml.Marshal(details) + details, err := yaml.MarshalWithOptions(resp, yaml.IndentSequence(true), yaml.UseJSONMarshaler()) if err != nil { - return fmt.Errorf("marshal output to YAML: %w", err) + return fmt.Errorf("marshal KMS key: %w", err) } - p.Outputln(string(b)) - return nil + p.Outputln(string(details)) default: - p.Outputf("Destroyed version %d of key '%q'\n", versionNumber, keyName) - return nil + p.Outputf("Destroyed version %d of key '%s'\n", utils.PtrValue(resp.Number), utils.PtrValue(resp.KeyId)) } + + return nil } diff --git a/internal/cmd/beta/kms/version/destroy/destroy_test.go b/internal/cmd/beta/kms/version/destroy/destroy_test.go index 407a87d8d..b407f3a8b 100644 --- a/internal/cmd/beta/kms/version/destroy/destroy_test.go +++ b/internal/cmd/beta/kms/version/destroy/destroy_test.go @@ -7,17 +7,16 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/uuid" - "github.com/spf13/cobra" "github.com/stackitcloud/stackit-cli/internal/cmd/params" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/print" - "github.com/stackitcloud/stackit-cli/internal/pkg/utils" "github.com/stackitcloud/stackit-sdk-go/services/kms" ) const ( - testRegion = "eu02" - testVersionNumber = int64(1) + testRegion = "eu02" + testVersionNumber = int64(1) + testVersionNumberString = "1" ) type testCtxKey struct{} @@ -30,6 +29,17 @@ var ( testKeyId = uuid.NewString() ) +// Args +func fixtureArgValues(mods ...func(argValues []string)) []string { + argValues := []string{ + testVersionNumberString, + } + for _, mod := range mods { + mod(argValues) + } + return argValues +} + // Flags func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]string { flagValues := map[string]string{ @@ -37,7 +47,6 @@ func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]st globalflags.RegionFlag: testRegion, keyRingIdFlag: testKeyRingId, keyIdFlag: testKeyId, - versionNumberFlag: "1", } for _, mod := range mods { mod(flagValues) @@ -55,7 +64,7 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { }, KeyRingId: testKeyRingId, KeyId: testKeyId, - VersionNumber: utils.Ptr(testVersionNumber), + VersionNumber: testVersionNumber, } for _, mod := range mods { mod(model) @@ -75,23 +84,33 @@ func fixtureRequest(mods ...func(request *kms.ApiDestroyVersionRequest)) kms.Api func TestParseInput(t *testing.T) { tests := []struct { description string + argValues []string flagValues map[string]string isValid bool expectedModel *inputModel }{ { description: "base", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(), expectedModel: fixtureInputModel(), isValid: true, }, + { + description: "no args (versionNumber)", + argValues: []string{}, + flagValues: fixtureFlagValues(), + isValid: false, + }, { description: "no values", + argValues: fixtureArgValues(), flagValues: map[string]string{}, isValid: false, }, { description: "project id missing", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { delete(flagValues, globalflags.ProjectIdFlag) }), @@ -99,6 +118,7 @@ func TestParseInput(t *testing.T) { }, { description: "project id invalid 1", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[globalflags.ProjectIdFlag] = "" }), @@ -106,6 +126,7 @@ func TestParseInput(t *testing.T) { }, { description: "project id invalid 2", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[globalflags.ProjectIdFlag] = "invalid-uuid" }), @@ -113,6 +134,7 @@ func TestParseInput(t *testing.T) { }, { description: "key ring id missing", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { delete(flagValues, keyRingIdFlag) }), @@ -120,6 +142,7 @@ func TestParseInput(t *testing.T) { }, { description: "key ring id invalid 1", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[keyRingIdFlag] = "" }), @@ -127,6 +150,7 @@ func TestParseInput(t *testing.T) { }, { description: "key ring id invalid 2", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[keyRingIdFlag] = "invalid-uuid" }), @@ -134,6 +158,7 @@ func TestParseInput(t *testing.T) { }, { description: "key id missing", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { delete(flagValues, keyIdFlag) }), @@ -141,6 +166,7 @@ func TestParseInput(t *testing.T) { }, { description: "key id invalid 1", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[keyIdFlag] = "" }), @@ -148,43 +174,42 @@ func TestParseInput(t *testing.T) { }, { description: "key id invalid 2", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[keyIdFlag] = "invalid-uuid" }), isValid: false, }, - { - description: "version number missing", - flagValues: fixtureFlagValues(func(flagValues map[string]string) { - delete(flagValues, versionNumberFlag) - }), - isValid: false, - }, { description: "version number invalid 1", - flagValues: fixtureFlagValues(func(flagValues map[string]string) { - flagValues[keyIdFlag] = "" - }), - isValid: false, + argValues: []string{""}, + flagValues: fixtureFlagValues(), + isValid: false, }, { description: "version number invalid 2", - flagValues: fixtureFlagValues(func(flagValues map[string]string) { - flagValues[keyIdFlag] = "invalid-number" - }), - isValid: false, + argValues: []string{"Not a Number!"}, + flagValues: fixtureFlagValues(), + isValid: false, }, } for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { - cmd := &cobra.Command{} + p := print.NewPrinter() + cmd := NewCmd(¶ms.CmdParams{Printer: p}) err := globalflags.Configure(cmd.Flags()) if err != nil { t.Fatalf("configure global flags: %v", err) } - configureFlags(cmd) + err = cmd.ValidateArgs(tt.argValues) + if err != nil { + if !tt.isValid { + return + } + t.Fatalf("error validating args: %v", err) + } for flag, value := range tt.flagValues { err := cmd.Flags().Set(flag, value) @@ -204,8 +229,7 @@ func TestParseInput(t *testing.T) { t.Fatalf("error validating flags: %v", err) } - p := print.NewPrinter() - model, err := parseInput(p, cmd) + model, err := parseInput(p, cmd, tt.argValues) if err != nil { if !tt.isValid { return @@ -254,35 +278,26 @@ func TestBuildRequest(t *testing.T) { func TestOutputResult(t *testing.T) { tests := []struct { - description string - wantErr bool - outputFormat string - versionNumber int64 - keyId string - keyName string + description string + wantErr bool + outputFormat string + resp *kms.Version }{ { - description: "default output", - versionNumber: 1, - keyId: uuid.NewString(), - keyName: "your-key", - wantErr: false, + description: "default output", + resp: &kms.Version{}, + wantErr: false, }, { - description: "json output", - outputFormat: print.JSONOutputFormat, - versionNumber: 1, - keyId: uuid.NewString(), - keyName: "your-key", - wantErr: false, + description: "json output", + resp: &kms.Version{}, + wantErr: false, }, { - description: "yaml output", - outputFormat: print.YAMLOutputFormat, - versionNumber: 1, - keyId: uuid.NewString(), - keyName: "your-key", - wantErr: false, + description: "yaml output", + resp: &kms.Version{}, + outputFormat: print.YAMLOutputFormat, + wantErr: false, }, } @@ -290,7 +305,7 @@ func TestOutputResult(t *testing.T) { p.Cmd = NewCmd(¶ms.CmdParams{Printer: p}) for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { - err := outputResult(p, tt.outputFormat, tt.versionNumber, tt.keyId, tt.keyName) + err := outputResult(p, tt.outputFormat, tt.resp) if (err != nil) != tt.wantErr { t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr) } diff --git a/internal/cmd/beta/kms/version/disable/disable.go b/internal/cmd/beta/kms/version/disable/disable.go index 1234cfd22..8eed8e32b 100644 --- a/internal/cmd/beta/kms/version/disable/disable.go +++ b/internal/cmd/beta/kms/version/disable/disable.go @@ -4,7 +4,9 @@ import ( "context" "encoding/json" "fmt" + "strconv" + "github.com/goccy/go-yaml" "github.com/spf13/cobra" "github.com/stackitcloud/stackit-cli/internal/cmd/params" "github.com/stackitcloud/stackit-cli/internal/pkg/args" @@ -14,40 +16,38 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/print" "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/client" - kmsUtils "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/utils" - "github.com/stackitcloud/stackit-cli/internal/pkg/spinner" + "github.com/stackitcloud/stackit-cli/internal/pkg/utils" "github.com/stackitcloud/stackit-sdk-go/services/kms" - "github.com/stackitcloud/stackit-sdk-go/services/kms/wait" - "gopkg.in/yaml.v2" ) const ( - keyRingIdFlag = "key-ring" - keyIdFlag = "key" - versionNumberFlag = "version" + versionNumberArg = "VERSION_NUMBER" + + keyRingIdFlag = "key-ring-id" + keyIdFlag = "key-id" ) type inputModel struct { *globalflags.GlobalFlagModel KeyRingId string KeyId string - VersionNumber *int64 + VersionNumber int64 } func NewCmd(params *params.CmdParams) *cobra.Command { cmd := &cobra.Command{ - Use: "disable", + Use: fmt.Sprintf("disable %s", versionNumberArg), Short: "Disable a key version", Long: "Disable the given key version.", - Args: args.NoArgs, + Args: args.SingleArg(versionNumberArg, nil), Example: examples.Build( examples.NewExample( - `Disable key version "0" for the key "my-key-id" inside the key ring "my-key-ring-id"`, - `$ stackit beta kms version disable --key "my-key-id" --key-ring "my-key-ring-id" --version 0`), + `Disable key version "42" for the key "my-key-id" inside the key ring "my-key-ring-id"`, + `$ stackit beta kms version disable 42 --key "my-key-id" --key-ring "my-key-ring-id"`), ), - RunE: func(cmd *cobra.Command, _ []string) error { + RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() - model, err := parseInput(params.Printer, cmd) + model, err := parseInput(params.Printer, cmd, args) if err != nil { return err } @@ -58,12 +58,6 @@ func NewCmd(params *params.CmdParams) *cobra.Command { return err } - keyName, err := kmsUtils.GetKeyName(ctx, apiClient, model.ProjectId, model.Region, model.KeyRingId, model.KeyId) - if err != nil { - params.Printer.Debug(print.ErrorLevel, "get key name: %v", err) - keyName = model.KeyId - } - // This operation can be undone. Don't ask for confirmation! // Call API @@ -73,18 +67,15 @@ func NewCmd(params *params.CmdParams) *cobra.Command { return fmt.Errorf("disable key version: %w", err) } - // Wait for async operation, if async mode not enabled - if !model.Async { - s := spinner.New(params.Printer) - s.Start("Disableing key version") - _, err = wait.DisableKeyVersionWaitHandler(ctx, apiClient, model.ProjectId, model.Region, model.KeyRingId, model.KeyId, *model.VersionNumber).WaitWithContext(ctx) - if err != nil { - return fmt.Errorf("wait for key version to be disabled: %w", err) - } - s.Stop() + // kms v1.0.0 has a waiter, but it get's stuck even though the disable api call was already successfully completed. + + // Get the key version in its state afterwards + resp, err := apiClient.GetVersionExecute(ctx, model.ProjectId, model.Region, model.KeyRingId, model.KeyId, model.VersionNumber) + if err != nil { + params.Printer.Debug(print.ErrorLevel, "get key version: %v", err) } - return outputResult(params.Printer, model.OutputFormat, *model.VersionNumber, model.KeyId, keyName) + return outputResult(params.Printer, model.OutputFormat, resp) }, } @@ -92,7 +83,16 @@ func NewCmd(params *params.CmdParams) *cobra.Command { return cmd } -func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { +func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inputModel, error) { + versionStr := inputArgs[0] + versionNumber, err := strconv.ParseInt(versionStr, 10, 64) + if err != nil || versionNumber < 0 { + return nil, &errors.ArgValidationError{ + Arg: versionNumberArg, + Details: fmt.Sprintf("invalid value %q: must be a positive integer", versionStr), + } + } + globalFlags := globalflags.Parse(p, cmd) if globalFlags.ProjectId == "" { return nil, &errors.ProjectIdError{} @@ -102,7 +102,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { GlobalFlagModel: globalFlags, KeyRingId: flags.FlagToStringValue(p, cmd, keyRingIdFlag), KeyId: flags.FlagToStringValue(p, cmd, keyIdFlag), - VersionNumber: flags.FlagToInt64Pointer(p, cmd, versionNumberFlag), + VersionNumber: versionNumber, } if p.IsVerbosityDebug() { @@ -118,60 +118,40 @@ func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { } func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClient) kms.ApiDisableVersionRequest { - return apiClient.DisableVersion(ctx, model.ProjectId, model.Region, model.KeyRingId, model.KeyId, *model.VersionNumber) + return apiClient.DisableVersion(ctx, model.ProjectId, model.Region, model.KeyRingId, model.KeyId, model.VersionNumber) } func configureFlags(cmd *cobra.Command) { cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS key ring") cmd.Flags().Var(flags.UUIDFlag(), keyIdFlag, "ID of the rey") - cmd.Flags().Int64(versionNumberFlag, 0, "Version number of the key") - err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, keyIdFlag, versionNumberFlag) + err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, keyIdFlag) cobra.CheckErr(err) } -func outputResult(p *print.Printer, outputFormat string, versionNumber int64, keyId, keyName string) error { +func outputResult(p *print.Printer, outputFormat string, resp *kms.Version) error { + if resp == nil { + return fmt.Errorf("response is nil") + } + switch outputFormat { case print.JSONOutputFormat: - details := struct { - KeyId string `json:"keyId"` - KeyName string `json:"keyName"` - VersionNumber int64 `json:"versionNumber"` - Status string `json:"status"` - }{ - KeyId: keyId, - KeyName: keyName, - VersionNumber: versionNumber, - Status: fmt.Sprintf("Disabled version %d of key '%s'.", versionNumber, keyName), - } - b, err := json.MarshalIndent(details, "", " ") + details, err := json.MarshalIndent(resp, "", " ") if err != nil { - return fmt.Errorf("marshal output to JSON: %w", err) + return fmt.Errorf("marshal KMS key: %w", err) } - p.Outputln(string(b)) - return nil + p.Outputln(string(details)) case print.YAMLOutputFormat: - details := struct { - KeyId string `yaml:"keyId"` - KeyName string `yaml:"keyName"` - VersionNumber int64 `yaml:"versionNumber"` - Status string `yaml:"status"` - }{ - KeyId: keyId, - KeyName: keyName, - VersionNumber: versionNumber, - Status: fmt.Sprintf("Disabled version %d of key '%s'.", versionNumber, keyName), - } - b, err := yaml.Marshal(details) + details, err := yaml.MarshalWithOptions(resp, yaml.IndentSequence(true), yaml.UseJSONMarshaler()) if err != nil { - return fmt.Errorf("marshal output to YAML: %w", err) + return fmt.Errorf("marshal KMS key: %w", err) } - p.Outputln(string(b)) - return nil + p.Outputln(string(details)) default: - p.Outputf("Disabled version %d of key '%q'\n", versionNumber, keyName) - return nil + p.Outputf("Disabled version %d of key '%s'\n", utils.PtrValue(resp.Number), utils.PtrValue(resp.KeyId)) } + + return nil } diff --git a/internal/cmd/beta/kms/version/disable/disable_test.go b/internal/cmd/beta/kms/version/disable/disable_test.go index 22784abe9..571e791f1 100644 --- a/internal/cmd/beta/kms/version/disable/disable_test.go +++ b/internal/cmd/beta/kms/version/disable/disable_test.go @@ -7,17 +7,16 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/uuid" - "github.com/spf13/cobra" "github.com/stackitcloud/stackit-cli/internal/cmd/params" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/print" - "github.com/stackitcloud/stackit-cli/internal/pkg/utils" "github.com/stackitcloud/stackit-sdk-go/services/kms" ) const ( - testRegion = "eu02" - testVersionNumber = int64(1) + testRegion = "eu02" + testVersionNumber = int64(1) + testVersionNumberString = "1" ) type testCtxKey struct{} @@ -30,6 +29,17 @@ var ( testKeyId = uuid.NewString() ) +// Args +func fixtureArgValues(mods ...func(argValues []string)) []string { + argValues := []string{ + testVersionNumberString, + } + for _, mod := range mods { + mod(argValues) + } + return argValues +} + // Flags func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]string { flagValues := map[string]string{ @@ -37,7 +47,6 @@ func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]st globalflags.RegionFlag: testRegion, keyRingIdFlag: testKeyRingId, keyIdFlag: testKeyId, - versionNumberFlag: "1", } for _, mod := range mods { mod(flagValues) @@ -55,7 +64,7 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { }, KeyRingId: testKeyRingId, KeyId: testKeyId, - VersionNumber: utils.Ptr(testVersionNumber), + VersionNumber: testVersionNumber, } for _, mod := range mods { mod(model) @@ -75,23 +84,33 @@ func fixtureRequest(mods ...func(request *kms.ApiDisableVersionRequest)) kms.Api func TestParseInput(t *testing.T) { tests := []struct { description string + argValues []string flagValues map[string]string isValid bool expectedModel *inputModel }{ { description: "base", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(), expectedModel: fixtureInputModel(), isValid: true, }, + { + description: "no args (versionNumber)", + argValues: []string{}, + flagValues: fixtureFlagValues(), + isValid: false, + }, { description: "no values", + argValues: fixtureArgValues(), flagValues: map[string]string{}, isValid: false, }, { description: "project id missing", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { delete(flagValues, globalflags.ProjectIdFlag) }), @@ -99,6 +118,7 @@ func TestParseInput(t *testing.T) { }, { description: "project id invalid 1", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[globalflags.ProjectIdFlag] = "" }), @@ -106,6 +126,7 @@ func TestParseInput(t *testing.T) { }, { description: "project id invalid 2", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[globalflags.ProjectIdFlag] = "invalid-uuid" }), @@ -113,6 +134,7 @@ func TestParseInput(t *testing.T) { }, { description: "key ring id missing", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { delete(flagValues, keyRingIdFlag) }), @@ -120,6 +142,7 @@ func TestParseInput(t *testing.T) { }, { description: "key ring id invalid 1", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[keyRingIdFlag] = "" }), @@ -127,6 +150,7 @@ func TestParseInput(t *testing.T) { }, { description: "key ring id invalid 2", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[keyRingIdFlag] = "invalid-uuid" }), @@ -134,6 +158,7 @@ func TestParseInput(t *testing.T) { }, { description: "key id missing", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { delete(flagValues, keyIdFlag) }), @@ -141,6 +166,7 @@ func TestParseInput(t *testing.T) { }, { description: "key id invalid 1", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[keyIdFlag] = "" }), @@ -148,43 +174,42 @@ func TestParseInput(t *testing.T) { }, { description: "key id invalid 2", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[keyIdFlag] = "invalid-uuid" }), isValid: false, }, - { - description: "version number missing", - flagValues: fixtureFlagValues(func(flagValues map[string]string) { - delete(flagValues, versionNumberFlag) - }), - isValid: false, - }, { description: "version number invalid 1", - flagValues: fixtureFlagValues(func(flagValues map[string]string) { - flagValues[keyIdFlag] = "" - }), - isValid: false, + argValues: []string{""}, + flagValues: fixtureFlagValues(), + isValid: false, }, { description: "version number invalid 2", - flagValues: fixtureFlagValues(func(flagValues map[string]string) { - flagValues[keyIdFlag] = "invalid-number" - }), - isValid: false, + argValues: []string{"Not a Number!"}, + flagValues: fixtureFlagValues(), + isValid: false, }, } for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { - cmd := &cobra.Command{} + p := print.NewPrinter() + cmd := NewCmd(¶ms.CmdParams{Printer: p}) err := globalflags.Configure(cmd.Flags()) if err != nil { t.Fatalf("configure global flags: %v", err) } - configureFlags(cmd) + err = cmd.ValidateArgs(tt.argValues) + if err != nil { + if !tt.isValid { + return + } + t.Fatalf("error validating args: %v", err) + } for flag, value := range tt.flagValues { err := cmd.Flags().Set(flag, value) @@ -204,8 +229,7 @@ func TestParseInput(t *testing.T) { t.Fatalf("error validating flags: %v", err) } - p := print.NewPrinter() - model, err := parseInput(p, cmd) + model, err := parseInput(p, cmd, tt.argValues) if err != nil { if !tt.isValid { return @@ -254,35 +278,27 @@ func TestBuildRequest(t *testing.T) { func TestOutputResult(t *testing.T) { tests := []struct { - description string - wantErr bool - outputFormat string - versionNumber int64 - keyId string - keyName string + description string + wantErr bool + outputFormat string + resp *kms.Version }{ { - description: "default output", - versionNumber: 1, - keyId: uuid.NewString(), - keyName: "your-key", - wantErr: false, + description: "default output", + resp: &kms.Version{}, + wantErr: false, }, { - description: "json output", - outputFormat: print.JSONOutputFormat, - versionNumber: 1, - keyId: uuid.NewString(), - keyName: "your-key", - wantErr: false, + description: "json output", + outputFormat: print.JSONOutputFormat, + resp: &kms.Version{}, + wantErr: false, }, { - description: "yaml output", - outputFormat: print.YAMLOutputFormat, - versionNumber: 1, - keyId: uuid.NewString(), - keyName: "your-key", - wantErr: false, + description: "yaml output", + outputFormat: print.YAMLOutputFormat, + resp: &kms.Version{}, + wantErr: false, }, } @@ -290,7 +306,7 @@ func TestOutputResult(t *testing.T) { p.Cmd = NewCmd(¶ms.CmdParams{Printer: p}) for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { - err := outputResult(p, tt.outputFormat, tt.versionNumber, tt.keyId, tt.keyName) + err := outputResult(p, tt.outputFormat, tt.resp) if (err != nil) != tt.wantErr { t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr) } diff --git a/internal/cmd/beta/kms/version/enable/enable.go b/internal/cmd/beta/kms/version/enable/enable.go index 7b5d99dce..12c83e188 100644 --- a/internal/cmd/beta/kms/version/enable/enable.go +++ b/internal/cmd/beta/kms/version/enable/enable.go @@ -4,7 +4,9 @@ import ( "context" "encoding/json" "fmt" + "strconv" + "github.com/goccy/go-yaml" "github.com/spf13/cobra" "github.com/stackitcloud/stackit-cli/internal/cmd/params" "github.com/stackitcloud/stackit-cli/internal/pkg/args" @@ -14,40 +16,40 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/print" "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/client" - kmsUtils "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/utils" "github.com/stackitcloud/stackit-cli/internal/pkg/spinner" + "github.com/stackitcloud/stackit-cli/internal/pkg/utils" "github.com/stackitcloud/stackit-sdk-go/services/kms" "github.com/stackitcloud/stackit-sdk-go/services/kms/wait" - "gopkg.in/yaml.v2" ) const ( - keyRingIdFlag = "key-ring" - keyIdFlag = "key" - versionNumberFlag = "version" + versionNumberArg = "VERSION_NUMBER" + + keyRingIdFlag = "key-ring-id" + keyIdFlag = "key-id" ) type inputModel struct { *globalflags.GlobalFlagModel KeyRingId string KeyId string - VersionNumber *int64 + VersionNumber int64 } func NewCmd(params *params.CmdParams) *cobra.Command { cmd := &cobra.Command{ - Use: "enable", + Use: fmt.Sprintf("enable %s", versionNumberArg), Short: "Enable a key version", Long: "Enable the given key version.", - Args: args.NoArgs, + Args: args.SingleArg(versionNumberArg, nil), Example: examples.Build( examples.NewExample( - `Enable key version "0" for the key "my-key-id" inside the key ring "my-key-ring-id"`, - `$ stackit beta kms version enable --key "my-key-id" --key-ring "my-key-ring-id" --version 0`), + `Enable key version "42" for the key "my-key-id" inside the key ring "my-key-ring-id"`, + `$ stackit beta kms version enable 42 --key "my-key-id" --key-ring "my-key-ring-id"`), ), - RunE: func(cmd *cobra.Command, _ []string) error { + RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() - model, err := parseInput(params.Printer, cmd) + model, err := parseInput(params.Printer, cmd, args) if err != nil { return err } @@ -58,12 +60,6 @@ func NewCmd(params *params.CmdParams) *cobra.Command { return err } - keyName, err := kmsUtils.GetKeyName(ctx, apiClient, model.ProjectId, model.Region, model.KeyRingId, model.KeyId) - if err != nil { - params.Printer.Debug(print.ErrorLevel, "get key name: %v", err) - keyName = model.KeyId - } - // This operation can be undone. Don't ask for confirmation! // Call API @@ -77,14 +73,20 @@ func NewCmd(params *params.CmdParams) *cobra.Command { if !model.Async { s := spinner.New(params.Printer) s.Start("Enabling key version") - _, err = wait.EnableKeyVersionWaitHandler(ctx, apiClient, model.ProjectId, model.Region, model.KeyRingId, model.KeyId, *model.VersionNumber).WaitWithContext(ctx) + _, err = wait.EnableKeyVersionWaitHandler(ctx, apiClient, model.ProjectId, model.Region, model.KeyRingId, model.KeyId, model.VersionNumber).WaitWithContext(ctx) if err != nil { return fmt.Errorf("wait for key version to be enabled: %w", err) } s.Stop() } - return outputResult(params.Printer, model.OutputFormat, *model.VersionNumber, model.KeyId, keyName) + // Get the key version in its state afterwards + resp, err := apiClient.GetVersionExecute(ctx, model.ProjectId, model.Region, model.KeyRingId, model.KeyId, model.VersionNumber) + if err != nil { + params.Printer.Debug(print.ErrorLevel, "get key version: %v", err) + } + + return outputResult(params.Printer, model.OutputFormat, resp) }, } @@ -92,7 +94,16 @@ func NewCmd(params *params.CmdParams) *cobra.Command { return cmd } -func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { +func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inputModel, error) { + versionStr := inputArgs[0] + versionNumber, err := strconv.ParseInt(versionStr, 10, 64) + if err != nil || versionNumber < 0 { + return nil, &errors.ArgValidationError{ + Arg: versionNumberArg, + Details: fmt.Sprintf("invalid value %q: must be a positive integer", versionStr), + } + } + globalFlags := globalflags.Parse(p, cmd) if globalFlags.ProjectId == "" { return nil, &errors.ProjectIdError{} @@ -102,7 +113,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { GlobalFlagModel: globalFlags, KeyRingId: flags.FlagToStringValue(p, cmd, keyRingIdFlag), KeyId: flags.FlagToStringValue(p, cmd, keyIdFlag), - VersionNumber: flags.FlagToInt64Pointer(p, cmd, versionNumberFlag), + VersionNumber: versionNumber, } if p.IsVerbosityDebug() { @@ -118,60 +129,40 @@ func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { } func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClient) kms.ApiEnableVersionRequest { - return apiClient.EnableVersion(ctx, model.ProjectId, model.Region, model.KeyRingId, model.KeyId, *model.VersionNumber) + return apiClient.EnableVersion(ctx, model.ProjectId, model.Region, model.KeyRingId, model.KeyId, model.VersionNumber) } func configureFlags(cmd *cobra.Command) { cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS key ring") cmd.Flags().Var(flags.UUIDFlag(), keyIdFlag, "ID of the key") - cmd.Flags().Int64(versionNumberFlag, 0, "Version number of the key") - err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, keyIdFlag, versionNumberFlag) + err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, keyIdFlag) cobra.CheckErr(err) } -func outputResult(p *print.Printer, outputFormat string, versionNumber int64, keyId, keyName string) error { +func outputResult(p *print.Printer, outputFormat string, resp *kms.Version) error { + if resp == nil { + return fmt.Errorf("response is nil") + } + switch outputFormat { case print.JSONOutputFormat: - details := struct { - KeyId string `json:"keyId"` - KeyName string `json:"keyName"` - VersionNumber int64 `json:"versionNumber"` - Status string `json:"status"` - }{ - KeyId: keyId, - KeyName: keyName, - VersionNumber: versionNumber, - Status: fmt.Sprintf("Enabled version %d of key '%s'.", versionNumber, keyName), - } - b, err := json.MarshalIndent(details, "", " ") + details, err := json.MarshalIndent(resp, "", " ") if err != nil { - return fmt.Errorf("marshal output to JSON: %w", err) + return fmt.Errorf("marshal KMS key: %w", err) } - p.Outputln(string(b)) - return nil + p.Outputln(string(details)) case print.YAMLOutputFormat: - details := struct { - KeyId string `yaml:"keyId"` - KeyName string `yaml:"keyName"` - VersionNumber int64 `yaml:"versionNumber"` - Status string `yaml:"status"` - }{ - KeyId: keyId, - KeyName: keyName, - VersionNumber: versionNumber, - Status: fmt.Sprintf("Enabled version %d of key '%s'.", versionNumber, keyName), - } - b, err := yaml.Marshal(details) + details, err := yaml.MarshalWithOptions(resp, yaml.IndentSequence(true), yaml.UseJSONMarshaler()) if err != nil { - return fmt.Errorf("marshal output to YAML: %w", err) + return fmt.Errorf("marshal KMS key: %w", err) } - p.Outputln(string(b)) - return nil + p.Outputln(string(details)) default: - p.Outputf("Enabled version %d of key '%q'\n", versionNumber, keyName) - return nil + p.Outputf("Enabled version %d of key '%s'\n", utils.PtrValue(resp.Number), utils.PtrValue(resp.KeyId)) } + + return nil } diff --git a/internal/cmd/beta/kms/version/enable/enable_test.go b/internal/cmd/beta/kms/version/enable/enable_test.go index 2e09a5d6d..bff55f829 100644 --- a/internal/cmd/beta/kms/version/enable/enable_test.go +++ b/internal/cmd/beta/kms/version/enable/enable_test.go @@ -7,17 +7,16 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/uuid" - "github.com/spf13/cobra" "github.com/stackitcloud/stackit-cli/internal/cmd/params" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/print" - "github.com/stackitcloud/stackit-cli/internal/pkg/utils" "github.com/stackitcloud/stackit-sdk-go/services/kms" ) const ( - testRegion = "eu02" - testVersionNumber = int64(1) + testRegion = "eu02" + testVersionNumber = int64(1) + testVersionNumberString = "1" ) type testCtxKey struct{} @@ -30,6 +29,17 @@ var ( testKeyId = uuid.NewString() ) +// Args +func fixtureArgValues(mods ...func(argValues []string)) []string { + argValues := []string{ + testVersionNumberString, + } + for _, mod := range mods { + mod(argValues) + } + return argValues +} + // Flags func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]string { flagValues := map[string]string{ @@ -37,7 +47,6 @@ func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]st globalflags.RegionFlag: testRegion, keyRingIdFlag: testKeyRingId, keyIdFlag: testKeyId, - versionNumberFlag: "1", } for _, mod := range mods { mod(flagValues) @@ -55,7 +64,7 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { }, KeyRingId: testKeyRingId, KeyId: testKeyId, - VersionNumber: utils.Ptr(testVersionNumber), + VersionNumber: testVersionNumber, } for _, mod := range mods { mod(model) @@ -75,23 +84,33 @@ func fixtureRequest(mods ...func(request *kms.ApiEnableVersionRequest)) kms.ApiE func TestParseInput(t *testing.T) { tests := []struct { description string + argValues []string flagValues map[string]string isValid bool expectedModel *inputModel }{ { description: "base", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(), expectedModel: fixtureInputModel(), isValid: true, }, + { + description: "no args (versionNumber)", + argValues: []string{}, + flagValues: fixtureFlagValues(), + isValid: false, + }, { description: "no values", + argValues: fixtureArgValues(), flagValues: map[string]string{}, isValid: false, }, { description: "project id missing", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { delete(flagValues, globalflags.ProjectIdFlag) }), @@ -99,6 +118,7 @@ func TestParseInput(t *testing.T) { }, { description: "project id invalid 1", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[globalflags.ProjectIdFlag] = "" }), @@ -106,6 +126,7 @@ func TestParseInput(t *testing.T) { }, { description: "project id invalid 2", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[globalflags.ProjectIdFlag] = "invalid-uuid" }), @@ -113,6 +134,7 @@ func TestParseInput(t *testing.T) { }, { description: "key ring id missing", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { delete(flagValues, keyRingIdFlag) }), @@ -120,6 +142,7 @@ func TestParseInput(t *testing.T) { }, { description: "key ring id invalid 1", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[keyRingIdFlag] = "" }), @@ -127,6 +150,7 @@ func TestParseInput(t *testing.T) { }, { description: "key ring id invalid 2", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[keyRingIdFlag] = "invalid-uuid" }), @@ -134,6 +158,7 @@ func TestParseInput(t *testing.T) { }, { description: "key id missing", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { delete(flagValues, keyIdFlag) }), @@ -141,6 +166,7 @@ func TestParseInput(t *testing.T) { }, { description: "key id invalid 1", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[keyIdFlag] = "" }), @@ -148,43 +174,42 @@ func TestParseInput(t *testing.T) { }, { description: "key id invalid 2", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[keyIdFlag] = "invalid-uuid" }), isValid: false, }, - { - description: "version number missing", - flagValues: fixtureFlagValues(func(flagValues map[string]string) { - delete(flagValues, versionNumberFlag) - }), - isValid: false, - }, { description: "version number invalid 1", - flagValues: fixtureFlagValues(func(flagValues map[string]string) { - flagValues[keyIdFlag] = "" - }), - isValid: false, + argValues: []string{""}, + flagValues: fixtureFlagValues(), + isValid: false, }, { description: "version number invalid 2", - flagValues: fixtureFlagValues(func(flagValues map[string]string) { - flagValues[keyIdFlag] = "invalid-number" - }), - isValid: false, + argValues: []string{"Not a Number!"}, + flagValues: fixtureFlagValues(), + isValid: false, }, } for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { - cmd := &cobra.Command{} + p := print.NewPrinter() + cmd := NewCmd(¶ms.CmdParams{Printer: p}) err := globalflags.Configure(cmd.Flags()) if err != nil { t.Fatalf("configure global flags: %v", err) } - configureFlags(cmd) + err = cmd.ValidateArgs(tt.argValues) + if err != nil { + if !tt.isValid { + return + } + t.Fatalf("error validating args: %v", err) + } for flag, value := range tt.flagValues { err := cmd.Flags().Set(flag, value) @@ -204,8 +229,7 @@ func TestParseInput(t *testing.T) { t.Fatalf("error validating flags: %v", err) } - p := print.NewPrinter() - model, err := parseInput(p, cmd) + model, err := parseInput(p, cmd, tt.argValues) if err != nil { if !tt.isValid { return @@ -254,35 +278,27 @@ func TestBuildRequest(t *testing.T) { func TestOutputResult(t *testing.T) { tests := []struct { - description string - wantErr bool - outputFormat string - versionNumber int64 - keyId string - keyName string + description string + wantErr bool + outputFormat string + resp *kms.Version }{ { - description: "default output", - versionNumber: 1, - keyId: uuid.NewString(), - keyName: "your-key", - wantErr: false, + description: "default output", + resp: &kms.Version{}, + wantErr: false, }, { - description: "json output", - outputFormat: print.JSONOutputFormat, - versionNumber: 1, - keyId: uuid.NewString(), - keyName: "your-key", - wantErr: false, + description: "json output", + resp: &kms.Version{}, + outputFormat: print.JSONOutputFormat, + wantErr: false, }, { - description: "yaml output", - outputFormat: print.YAMLOutputFormat, - versionNumber: 1, - keyId: uuid.NewString(), - keyName: "your-key", - wantErr: false, + description: "yaml output", + resp: &kms.Version{}, + outputFormat: print.YAMLOutputFormat, + wantErr: false, }, } @@ -290,7 +306,7 @@ func TestOutputResult(t *testing.T) { p.Cmd = NewCmd(¶ms.CmdParams{Printer: p}) for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { - err := outputResult(p, tt.outputFormat, tt.versionNumber, tt.keyId, tt.keyName) + err := outputResult(p, tt.outputFormat, tt.resp) if (err != nil) != tt.wantErr { t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr) } diff --git a/internal/cmd/beta/kms/version/list/list.go b/internal/cmd/beta/kms/version/list/list.go index ea50bae62..abd04c084 100644 --- a/internal/cmd/beta/kms/version/list/list.go +++ b/internal/cmd/beta/kms/version/list/list.go @@ -21,8 +21,8 @@ import ( ) const ( - keyRingIdFlag = "key-ring" - keyIdFlag = "key" + keyRingIdFlag = "key-ring-id" + keyIdFlag = "key-id" ) type inputModel struct { @@ -110,7 +110,6 @@ func outputResult(p *print.Printer, outputFormat, projectId, keyId string, versi } p.Outputln(string(details)) - return nil case print.YAMLOutputFormat: details, err := yaml.MarshalWithOptions(versions, yaml.IndentSequence(true), yaml.UseJSONMarshaler()) if err != nil { @@ -118,7 +117,6 @@ func outputResult(p *print.Printer, outputFormat, projectId, keyId string, versi } p.Outputln(string(details)) - return nil default: if len(versions) == 0 { p.Outputf("No key versions found for project %q for the key %q\n", projectId, keyId) @@ -142,9 +140,9 @@ func outputResult(p *print.Printer, outputFormat, projectId, keyId string, versi if err != nil { return fmt.Errorf("render table: %w", err) } - - return nil } + + return nil } func configureFlags(cmd *cobra.Command) { diff --git a/internal/cmd/beta/kms/version/restore/restore.go b/internal/cmd/beta/kms/version/restore/restore.go index 43dae80df..2f2e277ab 100644 --- a/internal/cmd/beta/kms/version/restore/restore.go +++ b/internal/cmd/beta/kms/version/restore/restore.go @@ -4,7 +4,9 @@ import ( "context" "encoding/json" "fmt" + "strconv" + "github.com/goccy/go-yaml" "github.com/spf13/cobra" "github.com/stackitcloud/stackit-cli/internal/cmd/params" "github.com/stackitcloud/stackit-cli/internal/pkg/args" @@ -14,38 +16,38 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/print" "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/client" - kmsUtils "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/utils" + "github.com/stackitcloud/stackit-cli/internal/pkg/utils" "github.com/stackitcloud/stackit-sdk-go/services/kms" - "gopkg.in/yaml.v2" ) const ( - keyRingIdFlag = "key-ring" - keyIdFlag = "key" - versionNumberFlag = "version" + versionNumberArg = "VERSION_NUMBER" + + keyRingIdFlag = "key-ring-id" + keyIdFlag = "key-id" ) type inputModel struct { *globalflags.GlobalFlagModel KeyRingId string KeyId string - VersionNumber *int64 + VersionNumber int64 } func NewCmd(params *params.CmdParams) *cobra.Command { cmd := &cobra.Command{ - Use: "restore", + Use: fmt.Sprintf("restore %s", versionNumberArg), Short: "Restore a key version", Long: "Restores the specified version of key.", - Args: args.NoArgs, + Args: args.SingleArg(versionNumberArg, nil), Example: examples.Build( examples.NewExample( - `Restore key version "0" for the key "my-key-id" inside the key ring "my-key-ring-id"`, - `$ stackit beta kms version restore --key "my-key-id" --key-ring "my-key-ring-id" --version 0`), + `Restore key version "42" for the key "my-key-id" inside the key ring "my-key-ring-id"`, + `$ stackit beta kms version restore 42 --key "my-key-id" --key-ring "my-key-ring-id"`), ), - RunE: func(cmd *cobra.Command, _ []string) error { + RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() - model, err := parseInput(params.Printer, cmd) + model, err := parseInput(params.Printer, cmd, args) if err != nil { return err } @@ -56,12 +58,6 @@ func NewCmd(params *params.CmdParams) *cobra.Command { return err } - keyName, err := kmsUtils.GetKeyName(ctx, apiClient, model.ProjectId, model.Region, model.KeyRingId, model.KeyId) - if err != nil { - params.Printer.Debug(print.ErrorLevel, "get key name: %v", err) - keyName = model.KeyId - } - // This operation can be undone. Don't ask for confirmation! // Call API @@ -71,7 +67,13 @@ func NewCmd(params *params.CmdParams) *cobra.Command { return fmt.Errorf("restore key Version: %w", err) } - return outputResult(params.Printer, model.OutputFormat, *model.VersionNumber, model.KeyId, keyName) + // Grab the key after the restore was applied to display the new state to the user. + resp, err := apiClient.GetVersionExecute(ctx, model.ProjectId, model.Region, model.KeyRingId, model.KeyId, model.VersionNumber) + if err != nil { + params.Printer.Debug(print.ErrorLevel, "get key version: %v", err) + } + + return outputResult(params.Printer, model.OutputFormat, resp) }, } @@ -79,7 +81,16 @@ func NewCmd(params *params.CmdParams) *cobra.Command { return cmd } -func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { +func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inputModel, error) { + versionStr := inputArgs[0] + versionNumber, err := strconv.ParseInt(versionStr, 10, 64) + if err != nil || versionNumber < 0 { + return nil, &errors.ArgValidationError{ + Arg: versionNumberArg, + Details: fmt.Sprintf("invalid value %q: must be a positive integer", versionStr), + } + } + globalFlags := globalflags.Parse(p, cmd) if globalFlags.ProjectId == "" { return nil, &errors.ProjectIdError{} @@ -89,7 +100,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { GlobalFlagModel: globalFlags, KeyRingId: flags.FlagToStringValue(p, cmd, keyRingIdFlag), KeyId: flags.FlagToStringValue(p, cmd, keyIdFlag), - VersionNumber: flags.FlagToInt64Pointer(p, cmd, versionNumberFlag), + VersionNumber: versionNumber, } if p.IsVerbosityDebug() { @@ -105,60 +116,38 @@ func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { } func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClient) kms.ApiRestoreVersionRequest { - return apiClient.RestoreVersion(ctx, model.ProjectId, model.Region, model.KeyRingId, model.KeyId, *model.VersionNumber) + return apiClient.RestoreVersion(ctx, model.ProjectId, model.Region, model.KeyRingId, model.KeyId, model.VersionNumber) } func configureFlags(cmd *cobra.Command) { cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS key ring") cmd.Flags().Var(flags.UUIDFlag(), keyIdFlag, "ID of the key") - cmd.Flags().Int64(versionNumberFlag, 0, "Version number of the key") - err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, keyIdFlag, versionNumberFlag) + err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, keyIdFlag) cobra.CheckErr(err) } -func outputResult(p *print.Printer, outputFormat string, versionNumber int64, keyId, keyName string) error { +func outputResult(p *print.Printer, outputFormat string, resp *kms.Version) error { + if resp == nil { + return fmt.Errorf("response from 'GetKeyExecute()' is nil") + } + switch outputFormat { case print.JSONOutputFormat: - details := struct { - KeyId string `json:"keyId"` - KeyName string `json:"keyName"` - VersionNumber int64 `json:"versionNumber"` - Status string `json:"status"` - }{ - KeyId: keyId, - KeyName: keyName, - VersionNumber: versionNumber, - Status: fmt.Sprintf("Restored version %d of key '%s'.", versionNumber, keyName), - } - b, err := json.MarshalIndent(details, "", " ") + details, err := json.MarshalIndent(resp, "", " ") if err != nil { return fmt.Errorf("marshal output to JSON: %w", err) } - p.Outputln(string(b)) - return nil - + p.Outputln(string(details)) case print.YAMLOutputFormat: - details := struct { - KeyId string `yaml:"keyId"` - KeyName string `yaml:"keyName"` - VersionNumber int64 `yaml:"versionNumber"` - Status string `yaml:"status"` - }{ - KeyId: keyId, - KeyName: keyName, - VersionNumber: versionNumber, - Status: fmt.Sprintf("Restored version %d of key '%s'.", versionNumber, keyName), - } - b, err := yaml.Marshal(details) + details, err := yaml.MarshalWithOptions(resp, yaml.IndentSequence(true), yaml.UseJSONMarshaler()) if err != nil { return fmt.Errorf("marshal output to YAML: %w", err) } - p.Outputln(string(b)) - return nil + p.Outputln(string(details)) default: - p.Outputf("Restored version %d of key '%q'\n", versionNumber, keyName) - return nil + p.Outputf("Restored version %d of key '%s'\n", utils.PtrValue(resp.Number), utils.PtrValue(resp.KeyId)) } + return nil } diff --git a/internal/cmd/beta/kms/version/restore/restore_test.go b/internal/cmd/beta/kms/version/restore/restore_test.go index dc4e6799b..3fefc6f81 100644 --- a/internal/cmd/beta/kms/version/restore/restore_test.go +++ b/internal/cmd/beta/kms/version/restore/restore_test.go @@ -7,17 +7,16 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/uuid" - "github.com/spf13/cobra" "github.com/stackitcloud/stackit-cli/internal/cmd/params" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/print" - "github.com/stackitcloud/stackit-cli/internal/pkg/utils" "github.com/stackitcloud/stackit-sdk-go/services/kms" ) const ( - testRegion = "eu02" - testVersionNumber = int64(1) + testRegion = "eu02" + testVersionNumber = int64(1) + testVersionNumberString = "1" ) type testCtxKey struct{} @@ -30,6 +29,17 @@ var ( testKeyId = uuid.NewString() ) +// Args +func fixtureArgValues(mods ...func(argValues []string)) []string { + argValues := []string{ + testVersionNumberString, + } + for _, mod := range mods { + mod(argValues) + } + return argValues +} + // Flags func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]string { flagValues := map[string]string{ @@ -37,7 +47,6 @@ func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]st globalflags.RegionFlag: testRegion, keyRingIdFlag: testKeyRingId, keyIdFlag: testKeyId, - versionNumberFlag: "1", } for _, mod := range mods { mod(flagValues) @@ -55,7 +64,7 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { }, KeyRingId: testKeyRingId, KeyId: testKeyId, - VersionNumber: utils.Ptr(testVersionNumber), + VersionNumber: testVersionNumber, } for _, mod := range mods { mod(model) @@ -75,23 +84,33 @@ func fixtureRequest(mods ...func(request *kms.ApiRestoreVersionRequest)) kms.Api func TestParseInput(t *testing.T) { tests := []struct { description string + argValues []string flagValues map[string]string isValid bool expectedModel *inputModel }{ { description: "base", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(), expectedModel: fixtureInputModel(), isValid: true, }, + { + description: "no args (versionNumber)", + argValues: []string{}, + flagValues: fixtureFlagValues(), + isValid: false, + }, { description: "no values", + argValues: fixtureArgValues(), flagValues: map[string]string{}, isValid: false, }, { description: "project id missing", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { delete(flagValues, globalflags.ProjectIdFlag) }), @@ -99,6 +118,7 @@ func TestParseInput(t *testing.T) { }, { description: "project id invalid 1", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[globalflags.ProjectIdFlag] = "" }), @@ -106,6 +126,7 @@ func TestParseInput(t *testing.T) { }, { description: "project id invalid 2", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[globalflags.ProjectIdFlag] = "invalid-uuid" }), @@ -113,6 +134,7 @@ func TestParseInput(t *testing.T) { }, { description: "key ring id missing", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { delete(flagValues, keyRingIdFlag) }), @@ -120,6 +142,7 @@ func TestParseInput(t *testing.T) { }, { description: "key ring id invalid 1", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[keyRingIdFlag] = "" }), @@ -127,6 +150,7 @@ func TestParseInput(t *testing.T) { }, { description: "key ring id invalid 2", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[keyRingIdFlag] = "invalid-uuid" }), @@ -134,6 +158,7 @@ func TestParseInput(t *testing.T) { }, { description: "key id missing", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { delete(flagValues, keyIdFlag) }), @@ -141,6 +166,7 @@ func TestParseInput(t *testing.T) { }, { description: "key id invalid 1", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[keyIdFlag] = "" }), @@ -148,43 +174,42 @@ func TestParseInput(t *testing.T) { }, { description: "key id invalid 2", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[keyIdFlag] = "invalid-uuid" }), isValid: false, }, - { - description: "version number missing", - flagValues: fixtureFlagValues(func(flagValues map[string]string) { - delete(flagValues, versionNumberFlag) - }), - isValid: false, - }, { description: "version number invalid 1", - flagValues: fixtureFlagValues(func(flagValues map[string]string) { - flagValues[keyIdFlag] = "" - }), - isValid: false, + argValues: []string{""}, + flagValues: fixtureFlagValues(), + isValid: false, }, { description: "version number invalid 2", - flagValues: fixtureFlagValues(func(flagValues map[string]string) { - flagValues[keyIdFlag] = "invalid-number" - }), - isValid: false, + argValues: []string{"Not a Number!"}, + flagValues: fixtureFlagValues(), + isValid: false, }, } for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { - cmd := &cobra.Command{} + p := print.NewPrinter() + cmd := NewCmd(¶ms.CmdParams{Printer: p}) err := globalflags.Configure(cmd.Flags()) if err != nil { t.Fatalf("configure global flags: %v", err) } - configureFlags(cmd) + err = cmd.ValidateArgs(tt.argValues) + if err != nil { + if !tt.isValid { + return + } + t.Fatalf("error validating args: %v", err) + } for flag, value := range tt.flagValues { err := cmd.Flags().Set(flag, value) @@ -204,8 +229,7 @@ func TestParseInput(t *testing.T) { t.Fatalf("error validating flags: %v", err) } - p := print.NewPrinter() - model, err := parseInput(p, cmd) + model, err := parseInput(p, cmd, tt.argValues) if err != nil { if !tt.isValid { return @@ -254,35 +278,27 @@ func TestBuildRequest(t *testing.T) { func TestOutputResult(t *testing.T) { tests := []struct { - description string - wantErr bool - outputFormat string - versionNumber int64 - keyId string - keyName string + description string + wantErr bool + outputFormat string + resp *kms.Version }{ { - description: "default output", - versionNumber: 1, - keyId: uuid.NewString(), - keyName: "your-key", - wantErr: false, + description: "default output", + resp: &kms.Version{}, + wantErr: false, }, { - description: "json output", - outputFormat: print.JSONOutputFormat, - versionNumber: 1, - keyId: uuid.NewString(), - keyName: "your-key", - wantErr: false, + description: "json output", + outputFormat: print.JSONOutputFormat, + resp: &kms.Version{}, + wantErr: false, }, { - description: "yaml output", - outputFormat: print.YAMLOutputFormat, - versionNumber: 1, - keyId: uuid.NewString(), - keyName: "your-key", - wantErr: false, + description: "yaml output", + outputFormat: print.YAMLOutputFormat, + resp: &kms.Version{}, + wantErr: false, }, } @@ -290,7 +306,7 @@ func TestOutputResult(t *testing.T) { p.Cmd = NewCmd(¶ms.CmdParams{Printer: p}) for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { - err := outputResult(p, tt.outputFormat, tt.versionNumber, tt.keyId, tt.keyName) + err := outputResult(p, tt.outputFormat, tt.resp) if (err != nil) != tt.wantErr { t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr) } diff --git a/internal/cmd/beta/kms/wrappingkey/create/create.go b/internal/cmd/beta/kms/wrappingkey/create/create.go index af1f4ae46..e70220887 100644 --- a/internal/cmd/beta/kms/wrappingkey/create/create.go +++ b/internal/cmd/beta/kms/wrappingkey/create/create.go @@ -24,12 +24,13 @@ import ( ) const ( - keyRingIdFlag = "key-ring" + keyRingIdFlag = "key-ring-id" algorithmFlag = "algorithm" descriptionFlag = "description" displayNameFlag = "name" purposeFlag = "purpose" + protectionFlag = "protection" ) type inputModel struct { @@ -40,6 +41,7 @@ type inputModel struct { Description *string Name *string Purpose *string + Protection *string } func NewCmd(params *params.CmdParams) *cobra.Command { @@ -51,10 +53,10 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Example: examples.Build( examples.NewExample( `Create a Symmetric KMS wrapping key`, - `$ stackit beta kms wrappingkey create --key-ring "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-wrapping-key-name" --purpose "wrap_symmetric_key"`), + `$ stackit beta kms wrappingkey create --key-ring "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-wrapping-key-name" --purpose "wrap_symmetric_key" --protection "software"`), examples.NewExample( `Create an Asymmetric KMS wrapping key with a description`, - `$ stackit beta kms wrappingkey create --key-ring "my-keyring-id" --algorithm "hmac_sha256" --name "my-wrapping-key-name" --description "my-description" --purpose "wrap_asymmetric_key"`), + `$ stackit beta kms wrappingkey create --key-ring "my-keyring-id" --algorithm "hmac_sha256" --name "my-wrapping-key-name" --description "my-description" --purpose "wrap_asymmetric_key" --protection "software"`), ), RunE: func(cmd *cobra.Command, _ []string) error { ctx := context.Background() @@ -85,10 +87,6 @@ func NewCmd(params *params.CmdParams) *cobra.Command { // Call API req, _ := buildRequest(ctx, model, apiClient) - if err != nil { - return err - } - wrappingKey, err := req.Execute() if err != nil { return fmt.Errorf("create KMS wrapping key: %w", err) @@ -126,6 +124,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { Name: flags.FlagToStringPointer(p, cmd, displayNameFlag), Description: flags.FlagToStringPointer(p, cmd, descriptionFlag), Purpose: flags.FlagToStringPointer(p, cmd, purposeFlag), + Protection: flags.FlagToStringPointer(p, cmd, protectionFlag), } if p.IsVerbosityDebug() { @@ -152,6 +151,7 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient kmsWrappingK Description: model.Description, Algorithm: kms.CreateWrappingKeyPayloadGetAlgorithmAttributeType(model.Algorithm), Purpose: kms.CreateWrappingKeyPayloadGetPurposeAttributeType(model.Purpose), + Protection: kms.CreateWrappingKeyPayloadGetProtectionAttributeType(model.Protection), }) return req, nil } @@ -168,7 +168,6 @@ func outputResult(p *print.Printer, outputFormat, projectLabel string, resp *kms return fmt.Errorf("marshal KMS wrapping key: %w", err) } p.Outputln(string(details)) - return nil case print.YAMLOutputFormat: details, err := yaml.MarshalWithOptions(resp, yaml.IndentSequence(true), yaml.UseJSONMarshaler()) @@ -176,12 +175,12 @@ func outputResult(p *print.Printer, outputFormat, projectLabel string, resp *kms return fmt.Errorf("marshal KMS wrapping key: %w", err) } p.Outputln(string(details)) - return nil default: p.Outputf("Created wrapping key for project %q. wrapping key ID: %s\n", projectLabel, utils.PtrString(resp.Id)) - return nil } + + return nil } func configureFlags(cmd *cobra.Command) { @@ -191,6 +190,9 @@ func configureFlags(cmd *cobra.Command) { cmd.Flags().String(descriptionFlag, "", "Optional description of the wrapping key") cmd.Flags().String(purposeFlag, "", "Purpose of the wrapping key. Enum: 'wrap_symmetric_key', 'wrap_asymmetric_key' ") - err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, algorithmFlag, purposeFlag, displayNameFlag) + // backend was deprectaed in /v1beta, but protection is a required attribute with value "software" + cmd.Flags().String(protectionFlag, "", "Protection of the wrapping key. Value: 'software' ") + + err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, algorithmFlag, purposeFlag, displayNameFlag, protectionFlag) cobra.CheckErr(err) } diff --git a/internal/cmd/beta/kms/wrappingkey/create/create_test.go b/internal/cmd/beta/kms/wrappingkey/create/create_test.go index 4eff07b10..ae55d9512 100644 --- a/internal/cmd/beta/kms/wrappingkey/create/create_test.go +++ b/internal/cmd/beta/kms/wrappingkey/create/create_test.go @@ -21,6 +21,7 @@ const ( testDisplayName = "my-key" testPurpose = "asymmetric_encrypt_decrypt" testDescription = "my key description" + testProtection = "software" ) type testCtxKey struct{} @@ -42,6 +43,7 @@ func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]st displayNameFlag: testDisplayName, purposeFlag: testPurpose, descriptionFlag: testDescription, + protectionFlag: testProtection, } for _, mod := range mods { mod(flagValues) @@ -62,6 +64,7 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { Name: utils.Ptr(testDisplayName), Purpose: utils.Ptr(testPurpose), Description: utils.Ptr(testDescription), + Protection: utils.Ptr(testProtection), } for _, mod := range mods { mod(model) @@ -77,6 +80,7 @@ func fixtureRequest(mods ...func(request *kms.ApiCreateWrappingKeyRequest)) kms. DisplayName: utils.Ptr(testDisplayName), Purpose: kms.CreateWrappingKeyPayloadGetPurposeAttributeType(utils.Ptr(testPurpose)), Description: utils.Ptr(testDescription), + Protection: kms.CreateWrappingKeyPayloadGetProtectionAttributeType(utils.Ptr(testProtection)), }) for _, mod := range mods { @@ -169,6 +173,13 @@ func TestParseInput(t *testing.T) { }), isValid: false, }, + { + description: "protection missing (required)", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, protectionFlag) + }), + isValid: false, + }, } for _, tt := range tests { @@ -239,6 +250,7 @@ func TestBuildRequest(t *testing.T) { Algorithm: kms.CreateWrappingKeyPayloadGetAlgorithmAttributeType(utils.Ptr(testAlgorithm)), DisplayName: utils.Ptr(testDisplayName), Purpose: kms.CreateWrappingKeyPayloadGetPurposeAttributeType(utils.Ptr(testPurpose)), + Protection: kms.CreateWrappingKeyPayloadGetProtectionAttributeType(utils.Ptr(testProtection)), }), }, } diff --git a/internal/cmd/beta/kms/wrappingkey/delete/delete.go b/internal/cmd/beta/kms/wrappingkey/delete/delete.go index d070a38f1..13a21eedc 100644 --- a/internal/cmd/beta/kms/wrappingkey/delete/delete.go +++ b/internal/cmd/beta/kms/wrappingkey/delete/delete.go @@ -2,7 +2,6 @@ package delete import ( "context" - "encoding/json" "fmt" "github.com/spf13/cobra" @@ -14,37 +13,38 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/print" kmsUtils "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/utils" - "gopkg.in/yaml.v2" + "github.com/stackitcloud/stackit-cli/internal/pkg/utils" "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/client" "github.com/stackitcloud/stackit-sdk-go/services/kms" ) const ( - keyRingIdFlag = "key-ring" - wrappingKeyIdFlag = "wrapping-key" + wrappingKeyIdArg = "WRAPPING_KEY_ID" + + keyRingIdFlag = "key-ring-id" ) type inputModel struct { *globalflags.GlobalFlagModel - KeyRingId string - WrappingKey string + WrappingKeyId string + KeyRingId string } func NewCmd(params *params.CmdParams) *cobra.Command { cmd := &cobra.Command{ - Use: "delete", + Use: fmt.Sprintf("delete %s", wrappingKeyIdArg), Short: "Deletes a KMS wrapping key", Long: "Deletes a KMS wrapping key inside a specific key ring.", - Args: args.NoArgs, + Args: args.SingleArg(wrappingKeyIdArg, utils.ValidateUUID), Example: examples.Build( examples.NewExample( `Delete a KMS wrapping key "my-wrapping-key-id" inside the key ring "my-key-ring-id"`, - `$ stackit beta kms keyring delete --key-ring "my-key-ring-id" --wrapping-key "my-wrapping-key-id"`), + `$ stackit beta kms keyring delete "my-wrapping-key-id" --key-ring "my-key-ring-id"`), ), - RunE: func(cmd *cobra.Command, _ []string) error { + RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() - model, err := parseInput(params.Printer, cmd) + model, err := parseInput(params.Printer, cmd, args) if err != nil { return err } @@ -55,14 +55,14 @@ func NewCmd(params *params.CmdParams) *cobra.Command { return err } - wrappingKeyName, err := kmsUtils.GetWrappingKeyName(ctx, apiClient, model.ProjectId, model.Region, model.KeyRingId, model.WrappingKey) + wrappingKeyName, err := kmsUtils.GetWrappingKeyName(ctx, apiClient, model.ProjectId, model.Region, model.KeyRingId, model.WrappingKeyId) if err != nil { params.Printer.Debug(print.ErrorLevel, "get wrapping key name: %v", err) - wrappingKeyName = model.WrappingKey + wrappingKeyName = model.WrappingKeyId } if !model.AssumeYes { - prompt := fmt.Sprintf("Are you sure you want to delete key ring %q? (This cannot be undone)", wrappingKeyName) + prompt := fmt.Sprintf("Are you sure you want to delete the wrapping key %q? (This cannot be undone)", wrappingKeyName) err = params.Printer.PromptForConfirmation(prompt) if err != nil { return err @@ -77,7 +77,10 @@ func NewCmd(params *params.CmdParams) *cobra.Command { } // Wait for async operation not relevant. Wrapping key deletion is synchronous - return outputResult(params.Printer, model.OutputFormat, wrappingKeyName) + + // Don't output anything. It's a deletion. + params.Printer.Info("Deleted wrapping key %q\n", wrappingKeyName) + return nil }, } @@ -85,7 +88,9 @@ func NewCmd(params *params.CmdParams) *cobra.Command { return cmd } -func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { +func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inputModel, error) { + wrappingKeyId := inputArgs[0] + globalFlags := globalflags.Parse(p, cmd) if globalFlags.ProjectId == "" { return nil, &errors.ProjectIdError{} @@ -94,7 +99,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { model := inputModel{ GlobalFlagModel: globalFlags, KeyRingId: flags.FlagToStringValue(p, cmd, keyRingIdFlag), - WrappingKey: flags.FlagToStringValue(p, cmd, wrappingKeyIdFlag), + WrappingKeyId: wrappingKeyId, } if p.IsVerbosityDebug() { @@ -110,51 +115,12 @@ func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { } func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClient) kms.ApiDeleteWrappingKeyRequest { - req := apiClient.DeleteWrappingKey(ctx, model.ProjectId, model.Region, model.KeyRingId, model.WrappingKey) + req := apiClient.DeleteWrappingKey(ctx, model.ProjectId, model.Region, model.KeyRingId, model.WrappingKeyId) return req } func configureFlags(cmd *cobra.Command) { cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS key ring where the wrapping key is stored") - cmd.Flags().Var(flags.UUIDFlag(), wrappingKeyIdFlag, "ID of the actual wrapping key") - err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, wrappingKeyIdFlag) + err := flags.MarkFlagsRequired(cmd, keyRingIdFlag) cobra.CheckErr(err) } - -func outputResult(p *print.Printer, outputFormat, wrappingKeyName string) error { - switch outputFormat { - case print.JSONOutputFormat: - details := struct { - WrappingKeyName string `json:"wrappingKeyName"` - Status string `json:"status"` - }{ - WrappingKeyName: wrappingKeyName, - Status: "Deleted wrapping key.", - } - b, err := json.MarshalIndent(details, "", " ") - if err != nil { - return fmt.Errorf("marshal output to JSON: %w", err) - } - p.Outputln(string(b)) - return nil - - case print.YAMLOutputFormat: - details := struct { - WrappingKeyName string `yaml:"wrappingKeyName"` - Status string `yaml:"status"` - }{ - WrappingKeyName: wrappingKeyName, - Status: "Deleted wrapping key.", - } - b, err := yaml.Marshal(details) - if err != nil { - return fmt.Errorf("marshal output to YAML: %w", err) - } - p.Outputln(string(b)) - return nil - - default: - p.Outputf("Deleted wrapping key: %s\n", wrappingKeyName) - return nil - } -} diff --git a/internal/cmd/beta/kms/wrappingkey/delete/delete_test.go b/internal/cmd/beta/kms/wrappingkey/delete/delete_test.go index bef3865f8..57be1cbfa 100644 --- a/internal/cmd/beta/kms/wrappingkey/delete/delete_test.go +++ b/internal/cmd/beta/kms/wrappingkey/delete/delete_test.go @@ -7,7 +7,6 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/uuid" - "github.com/spf13/cobra" "github.com/stackitcloud/stackit-cli/internal/cmd/params" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/print" @@ -21,20 +20,30 @@ const ( type testCtxKey struct{} var ( - testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") - testClient = &kms.APIClient{} - testProjectId = uuid.NewString() - testKeyRingId = uuid.NewString() - testWrappingKeyRingId = uuid.NewString() + testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") + testClient = &kms.APIClient{} + testProjectId = uuid.NewString() + testKeyRingId = uuid.NewString() + testWrappingKeyId = uuid.NewString() ) +// Args +func fixtureArgValues(mods ...func(argValues []string)) []string { + argValues := []string{ + testWrappingKeyId, + } + for _, mod := range mods { + mod(argValues) + } + return argValues +} + // Flags func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]string { flagValues := map[string]string{ globalflags.ProjectIdFlag: testProjectId, globalflags.RegionFlag: testRegion, keyRingIdFlag: testKeyRingId, - wrappingKeyIdFlag: testWrappingKeyRingId, } for _, mod := range mods { mod(flagValues) @@ -50,8 +59,8 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { Region: testRegion, Verbosity: globalflags.VerbosityDefault, }, - KeyRingId: testKeyRingId, - WrappingKey: testWrappingKeyRingId, + KeyRingId: testKeyRingId, + WrappingKeyId: testWrappingKeyId, } for _, mod := range mods { mod(model) @@ -61,7 +70,7 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { // Request func fixtureRequest(mods ...func(request *kms.ApiDeleteWrappingKeyRequest)) kms.ApiDeleteWrappingKeyRequest { - request := testClient.DeleteWrappingKey(testCtx, testProjectId, testRegion, testKeyRingId, testWrappingKeyRingId) + request := testClient.DeleteWrappingKey(testCtx, testProjectId, testRegion, testKeyRingId, testWrappingKeyId) for _, mod := range mods { mod(&request) } @@ -71,23 +80,33 @@ func fixtureRequest(mods ...func(request *kms.ApiDeleteWrappingKeyRequest)) kms. func TestParseInput(t *testing.T) { tests := []struct { description string + argValues []string flagValues map[string]string isValid bool expectedModel *inputModel }{ { description: "base", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(), isValid: true, expectedModel: fixtureInputModel(), }, + { + description: "no args (wrappingKeyId)", + argValues: []string{}, + flagValues: fixtureFlagValues(), + isValid: false, + }, { description: "no values provided", + argValues: fixtureArgValues(), flagValues: map[string]string{}, isValid: false, }, { description: "project id missing", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { delete(flagValues, globalflags.ProjectIdFlag) }), @@ -95,6 +114,7 @@ func TestParseInput(t *testing.T) { }, { description: "project id invalid 1", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[globalflags.ProjectIdFlag] = "" }), @@ -102,6 +122,7 @@ func TestParseInput(t *testing.T) { }, { description: "project id invalid 2", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[globalflags.ProjectIdFlag] = "invalid-uuid" }), @@ -109,6 +130,7 @@ func TestParseInput(t *testing.T) { }, { description: "key ring id missing (required)", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { delete(flagValues, keyRingIdFlag) }), @@ -116,43 +138,42 @@ func TestParseInput(t *testing.T) { }, { description: "key ring id invalid", + argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[keyRingIdFlag] = "invalid-uuid" }), isValid: false, }, - { - description: "wrapping key id missing (required)", - flagValues: fixtureFlagValues(func(flagValues map[string]string) { - delete(flagValues, wrappingKeyIdFlag) - }), - isValid: false, - }, { description: "wrapping key id invalid 1", - flagValues: fixtureFlagValues(func(flagValues map[string]string) { - flagValues[wrappingKeyIdFlag] = "" - }), - isValid: false, + argValues: []string{""}, + flagValues: fixtureFlagValues(), + isValid: false, }, { description: "wrapping key id invalid 2", - flagValues: fixtureFlagValues(func(flagValues map[string]string) { - flagValues[wrappingKeyIdFlag] = "invalid-uuid" - }), - isValid: false, + argValues: []string{"invalid-uuid"}, + flagValues: fixtureFlagValues(), + isValid: false, }, } for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { - cmd := &cobra.Command{} + p := print.NewPrinter() + cmd := NewCmd(¶ms.CmdParams{Printer: p}) err := globalflags.Configure(cmd.Flags()) if err != nil { t.Fatalf("configure global flags: %v", err) } - configureFlags(cmd) + err = cmd.ValidateArgs(tt.argValues) + if err != nil { + if !tt.isValid { + return + } + t.Fatalf("error validating args: %v", err) + } for flag, value := range tt.flagValues { err := cmd.Flags().Set(flag, value) @@ -172,8 +193,7 @@ func TestParseInput(t *testing.T) { t.Fatalf("error validating flags: %v", err) } - p := print.NewPrinter() - model, err := parseInput(p, cmd) + model, err := parseInput(p, cmd, tt.argValues) if err != nil { if !tt.isValid { return @@ -219,41 +239,3 @@ func TestBuildRequest(t *testing.T) { }) } } - -func TestOutputResult(t *testing.T) { - tests := []struct { - description string - wantErr bool - outputFormat string - wrappingKeyName string - }{ - { - description: "default output", - wrappingKeyName: "yourWrappingKey", - wantErr: false, - }, - { - description: "json output", - outputFormat: print.JSONOutputFormat, - wrappingKeyName: "yourWrappingKey", - wantErr: false, - }, - { - description: "yaml output", - outputFormat: print.YAMLOutputFormat, - wrappingKeyName: "yourWrappingKey", - wantErr: false, - }, - } - - p := print.NewPrinter() - p.Cmd = NewCmd(¶ms.CmdParams{Printer: p}) - for _, tt := range tests { - t.Run(tt.description, func(t *testing.T) { - err := outputResult(p, tt.outputFormat, tt.wrappingKeyName) - if (err != nil) != tt.wantErr { - t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr) - } - }) - } -} diff --git a/internal/cmd/beta/kms/wrappingkey/list/list.go b/internal/cmd/beta/kms/wrappingkey/list/list.go index b0eebe2e3..8f0deb386 100644 --- a/internal/cmd/beta/kms/wrappingkey/list/list.go +++ b/internal/cmd/beta/kms/wrappingkey/list/list.go @@ -11,6 +11,7 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/args" "github.com/stackitcloud/stackit-cli/internal/pkg/errors" "github.com/stackitcloud/stackit-cli/internal/pkg/examples" + "github.com/stackitcloud/stackit-cli/internal/pkg/flags" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/print" "github.com/stackitcloud/stackit-cli/internal/pkg/services/kms/client" @@ -20,7 +21,7 @@ import ( ) const ( - keyRingIdArg = "KEYRING_ID" + keyRingIdFlag = "key-ring-id" ) type inputModel struct { @@ -30,21 +31,21 @@ type inputModel struct { func NewCmd(params *params.CmdParams) *cobra.Command { cmd := &cobra.Command{ - Use: fmt.Sprintf("list %s", keyRingIdArg), + Use: "list", Short: "Lists all KMS wrapping keys", Long: "Lists all KMS wrapping keys inside a key ring.", - Args: args.SingleArg(keyRingIdArg, utils.ValidateUUID), + Args: args.NoArgs, Example: examples.Build( examples.NewExample( - `List all KMS wrapping keys for the key ring "xxx"`, - "$ stackit beta kms wrappingkeys list xxx"), + `List all KMS wrapping keys for the key ring "my-key-ring-id"`, + `$ stackit beta kms wrappingkeys list --key-ring "my-key-ring-id"`), examples.NewExample( `List all KMS wrapping keys in JSON format`, - "$ stackit beta kms wrappingkeys list xxx --output-format json"), + `$ stackit beta kms wrappingkeys list --key-ring "my-key-ring-id" --output-format json`), ), - RunE: func(cmd *cobra.Command, args []string) error { + RunE: func(cmd *cobra.Command, _ []string) error { ctx := context.Background() - model, err := parseInput(params.Printer, cmd, args) + model, err := parseInput(params.Printer, cmd) if err != nil { return err } @@ -62,15 +63,15 @@ func NewCmd(params *params.CmdParams) *cobra.Command { return fmt.Errorf("get KMS wrapping keys: %w", err) } - return outputResult(params.Printer, model.OutputFormat, model.ProjectId, model.KeyRingId, *resp.WrappingKeys) + return outputResult(params.Printer, model.OutputFormat, model.KeyRingId, *resp.WrappingKeys) }, } + + configureFlags(cmd) return cmd } -func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inputModel, error) { - keyRingId := inputArgs[0] - +func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { globalFlags := globalflags.Parse(p, cmd) if globalFlags.ProjectId == "" { return nil, &errors.ProjectIdError{} @@ -78,7 +79,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu model := inputModel{ GlobalFlagModel: globalFlags, - KeyRingId: keyRingId, + KeyRingId: flags.FlagToStringValue(p, cmd, keyRingIdFlag), } if p.IsVerbosityDebug() { @@ -98,7 +99,13 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClie return req } -func outputResult(p *print.Printer, outputFormat, projectId, keyRingId string, wrappingKeys []kms.WrappingKey) error { +func configureFlags(cmd *cobra.Command) { + cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS Key Ring where the Key is stored") + err := flags.MarkFlagsRequired(cmd, keyRingIdFlag) + cobra.CheckErr(err) +} + +func outputResult(p *print.Printer, outputFormat, keyRingId string, wrappingKeys []kms.WrappingKey) error { switch outputFormat { case print.JSONOutputFormat: details, err := json.MarshalIndent(wrappingKeys, "", " ") @@ -107,7 +114,6 @@ func outputResult(p *print.Printer, outputFormat, projectId, keyRingId string, w } p.Outputln(string(details)) - return nil case print.YAMLOutputFormat: details, err := yaml.MarshalWithOptions(wrappingKeys, yaml.IndentSequence(true), yaml.UseJSONMarshaler()) if err != nil { @@ -115,10 +121,9 @@ func outputResult(p *print.Printer, outputFormat, projectId, keyRingId string, w } p.Outputln(string(details)) - return nil default: if len(wrappingKeys) == 0 { - p.Outputf("No wrapping keys found for project %q under the key ring %q\n", projectId, keyRingId) + p.Outputf("No wrapping keys found under the key ring %q\n", keyRingId) return nil } table := tables.NewTable() @@ -141,7 +146,7 @@ func outputResult(p *print.Printer, outputFormat, projectId, keyRingId string, w if err != nil { return fmt.Errorf("render table: %w", err) } - - return nil } + + return nil } diff --git a/internal/cmd/beta/kms/wrappingkey/list/list_test.go b/internal/cmd/beta/kms/wrappingkey/list/list_test.go index 74a5facb9..10caf83d1 100644 --- a/internal/cmd/beta/kms/wrappingkey/list/list_test.go +++ b/internal/cmd/beta/kms/wrappingkey/list/list_test.go @@ -7,6 +7,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/uuid" + "github.com/spf13/cobra" "github.com/stackitcloud/stackit-cli/internal/cmd/params" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/print" @@ -26,22 +27,12 @@ var ( testKeyRingId = uuid.NewString() ) -// Args -func fixtureArgValues(mods ...func(argValues []string)) []string { - argValues := []string{ - testKeyRingId, - } - for _, mod := range mods { - mod(argValues) - } - return argValues -} - // Flags func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]string { flagValues := map[string]string{ globalflags.ProjectIdFlag: testProjectId, globalflags.RegionFlag: testRegion, + keyRingIdFlag: testKeyRingId, } for _, mod := range mods { mod(flagValues) @@ -77,41 +68,44 @@ func fixtureRequest(mods ...func(request *kms.ApiListWrappingKeysRequest)) kms.A func TestParseInput(t *testing.T) { tests := []struct { description string - argValues []string flagValues map[string]string isValid bool expectedModel *inputModel }{ { description: "base", - argValues: fixtureArgValues(), flagValues: fixtureFlagValues(), expectedModel: fixtureInputModel(), isValid: true, }, { - description: "no args (keyRingId)", - argValues: []string{}, - flagValues: fixtureFlagValues(), + description: "no values", + flagValues: map[string]string{}, isValid: false, }, { - description: "invalid keyRingId", - argValues: fixtureArgValues(func(argValues []string) { - argValues[0] = "Not an uuid" + description: "missing keyRingId", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, keyRingIdFlag) }), - flagValues: fixtureFlagValues(), - isValid: false, + isValid: false, }, { - description: "no values", - argValues: fixtureArgValues(), - flagValues: map[string]string{}, - isValid: false, + description: "invalid keyRingId 1", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyRingIdFlag] = "" + }), + isValid: false, + }, + { + description: "invalid keyRingId 2", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[keyRingIdFlag] = "Not an uuid" + }), + isValid: false, }, { description: "project id missing", - argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { delete(flagValues, globalflags.ProjectIdFlag) }), @@ -119,7 +113,6 @@ func TestParseInput(t *testing.T) { }, { description: "project id invalid 1", - argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[globalflags.ProjectIdFlag] = "" }), @@ -127,7 +120,6 @@ func TestParseInput(t *testing.T) { }, { description: "project id invalid 2", - argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[globalflags.ProjectIdFlag] = "invalid-uuid" }), @@ -137,13 +129,13 @@ func TestParseInput(t *testing.T) { for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { - p := print.NewPrinter() - cmd := NewCmd(¶ms.CmdParams{Printer: p}) + cmd := &cobra.Command{} err := globalflags.Configure(cmd.Flags()) if err != nil { t.Fatalf("configure global flags: %v", err) } + configureFlags(cmd) for flag, value := range tt.flagValues { err := cmd.Flags().Set(flag, value) if err != nil { @@ -154,14 +146,6 @@ func TestParseInput(t *testing.T) { } } - 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 { @@ -170,7 +154,8 @@ func TestParseInput(t *testing.T) { t.Fatalf("error validating flags: %v", err) } - model, err := parseInput(p, cmd, tt.argValues) + p := print.NewPrinter() + model, err := parseInput(p, cmd) if err != nil { if !tt.isValid { return @@ -220,7 +205,6 @@ func TestBuildRequest(t *testing.T) { func TestOutputResult(t *testing.T) { tests := []struct { description string - projectId string keyRingId string wrappingKeys []kms.WrappingKey outputFormat string @@ -251,7 +235,7 @@ func TestOutputResult(t *testing.T) { p.Cmd = NewCmd(¶ms.CmdParams{Printer: p}) for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { - err := outputResult(p, tt.outputFormat, tt.projectId, tt.keyRingId, tt.wrappingKeys) + err := outputResult(p, tt.outputFormat, tt.keyRingId, tt.wrappingKeys) if (err != nil) != tt.wantErr { t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr) } From e39d775f24107c6df868b8e400dd9710d05cb040 Mon Sep 17 00:00:00 2001 From: Jan Sternagel Date: Tue, 7 Oct 2025 16:06:02 +0200 Subject: [PATCH 27/52] updated the docs --- docs/stackit_beta_kms_key.md | 4 ++-- docs/stackit_beta_kms_key_create.md | 7 ++++--- docs/stackit_beta_kms_key_delete.md | 9 ++++----- docs/stackit_beta_kms_key_import.md | 9 ++++----- docs/stackit_beta_kms_key_list.md | 11 ++++++----- docs/stackit_beta_kms_key_restore.md | 11 +++++------ docs/stackit_beta_kms_key_rotate.md | 9 ++++----- docs/stackit_beta_kms_keyring_create.md | 4 ++-- docs/stackit_beta_kms_keyring_delete.md | 4 ++-- docs/stackit_beta_kms_version_destroy.md | 13 ++++++------- docs/stackit_beta_kms_version_disable.md | 13 ++++++------- docs/stackit_beta_kms_version_enable.md | 13 ++++++------- docs/stackit_beta_kms_version_list.md | 6 +++--- docs/stackit_beta_kms_version_restore.md | 13 ++++++------- docs/stackit_beta_kms_wrapping-key.md | 2 +- docs/stackit_beta_kms_wrapping-key_create.md | 7 ++++--- docs/stackit_beta_kms_wrapping-key_delete.md | 9 ++++----- docs/stackit_beta_kms_wrapping-key_list.md | 17 +++++++++-------- 18 files changed, 78 insertions(+), 83 deletions(-) diff --git a/docs/stackit_beta_kms_key.md b/docs/stackit_beta_kms_key.md index 2e6a0dbc2..69e829720 100644 --- a/docs/stackit_beta_kms_key.md +++ b/docs/stackit_beta_kms_key.md @@ -4,7 +4,7 @@ Manage KMS Keys ### Synopsis -Provides functionality for Key operations inside the KMS +Provides functionality for key operations inside the KMS ``` stackit beta kms key [flags] @@ -34,6 +34,6 @@ stackit beta kms key [flags] * [stackit beta kms key delete](./stackit_beta_kms_key_delete.md) - Deletes a KMS key * [stackit beta kms key import](./stackit_beta_kms_key_import.md) - Import a KMS key * [stackit beta kms key list](./stackit_beta_kms_key_list.md) - List all KMS keys -* [stackit beta kms key restore](./stackit_beta_kms_key_restore.md) - Resotre a key +* [stackit beta kms key restore](./stackit_beta_kms_key_restore.md) - Restore a key * [stackit beta kms key rotate](./stackit_beta_kms_key_rotate.md) - Rotate a key diff --git a/docs/stackit_beta_kms_key_create.md b/docs/stackit_beta_kms_key_create.md index 372109c00..60a59d8a2 100644 --- a/docs/stackit_beta_kms_key_create.md +++ b/docs/stackit_beta_kms_key_create.md @@ -14,10 +14,10 @@ stackit beta kms key create [flags] ``` Create a Symmetric KMS key - $ stackit beta kms key create --key-ring "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-key-name" --purpose "symmetric_encrypt_decrypt" + $ stackit beta kms key create --key-ring "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-key-name" --purpose "asymmetric_encrypt_decrypt" --protection "software" Create a Message Authentication KMS key - $ stackit beta kms key create --key-ring "my-keyring-id" --algorithm "hmac_sha512" --name "my-key-name" --purpose "message_authentication_code" + $ stackit beta kms key create --key-ring "my-keyring-id" --algorithm "hmac_sha512" --name "my-key-name" --purpose "message_authentication_code" --protection "software" ``` ### Options @@ -27,8 +27,9 @@ stackit beta kms key create [flags] --description string Optional description of the key -h, --help Help for "stackit beta kms key create" --import-only States whether versions can be created or only imported - --key-ring string ID of the KMS key ring + --key-ring-id string ID of the KMS key ring --name string The display name to distinguish multiple keys + --protection string The underlying system that is responsible for protecting the key material. Value: 'software' --purpose string Purpose of the key. Enum: 'symmetric_encrypt_decrypt', 'asymmetric_encrypt_decrypt', 'message_authentication_code', 'asymmetric_sign_verify' ``` diff --git a/docs/stackit_beta_kms_key_delete.md b/docs/stackit_beta_kms_key_delete.md index 5d2e05275..26d7e243b 100644 --- a/docs/stackit_beta_kms_key_delete.md +++ b/docs/stackit_beta_kms_key_delete.md @@ -7,22 +7,21 @@ Deletes a KMS key Deletes a KMS key inside a specific key ring. ``` -stackit beta kms key delete [flags] +stackit beta kms key delete KEY_ID [flags] ``` ### Examples ``` Delete a KMS key "my-key-id" inside the key ring "my-key-ring-id" - $ stackit beta kms keyring delete --key-ring "my-key-ring-id" --key "my-key-id" + $ stackit beta kms keyring delete "my-key-id" --key-ring "my-key-ring-id" ``` ### Options ``` - -h, --help Help for "stackit beta kms key delete" - --key string ID of the actual Key - --key-ring string ID of the KMS Key Ring where the Key is stored + -h, --help Help for "stackit beta kms key delete" + --key-ring-id string ID of the KMS Key Ring where the Key is stored ``` ### Options inherited from parent commands diff --git a/docs/stackit_beta_kms_key_import.md b/docs/stackit_beta_kms_key_import.md index 807632f0b..a7f8b6f4d 100644 --- a/docs/stackit_beta_kms_key_import.md +++ b/docs/stackit_beta_kms_key_import.md @@ -7,22 +7,21 @@ Import a KMS key Import a new version to the given KMS key. ``` -stackit beta kms key import [flags] +stackit beta kms key import KEY_ID [flags] ``` ### Examples ``` - Import a new version for the given KMS key "my-key" - $ stakit beta kms key import --key-ring "my-keyring-id" --key "my-key-id" --wrapped-key "base64-encoded-wrapped-key-material" --wrapping-key-id "my-wrapping-key-id" + Import a new version for the given KMS key "my-key-id" + $ stackit beta kms key import "my-key-id" --key-ring "my-keyring-id" --wrapped-key "base64-encoded-wrapped-key-material" --wrapping-key-id "my-wrapping-key-id" ``` ### Options ``` -h, --help Help for "stackit beta kms key import" - --key string ID of the KMS key - --key-ring string ID of the KMS key ring + --key-ring-id string ID of the KMS key ring --wrapped-key string The wrapped key material that has to be imported. Encoded in base64 --wrapping-key-id string The unique id of the wrapping key the key material has been wrapped with ``` diff --git a/docs/stackit_beta_kms_key_list.md b/docs/stackit_beta_kms_key_list.md index 818ff8e9e..3016764b1 100644 --- a/docs/stackit_beta_kms_key_list.md +++ b/docs/stackit_beta_kms_key_list.md @@ -7,23 +7,24 @@ List all KMS keys List all KMS keys inside a key ring. ``` -stackit beta kms key list KEYRING_ID [flags] +stackit beta kms key list [flags] ``` ### Examples ``` - List all KMS keys for the key ring "xxx" - $ stackit beta kms key list xxx + List all KMS keys for the key ring "my-key-ring-id" + $ stackit beta kms key list --key-ring "my-key-ring-id" List all KMS keys in JSON format - $ stackit beta kms key list xxx --output-format json + $ stackit beta kms key list --key-ring "my-key-ring-id" --output-format json ``` ### Options ``` - -h, --help Help for "stackit beta kms key list" + -h, --help Help for "stackit beta kms key list" + --key-ring-id string ID of the KMS Key Ring where the Key is stored ``` ### Options inherited from parent commands diff --git a/docs/stackit_beta_kms_key_restore.md b/docs/stackit_beta_kms_key_restore.md index 70c19b824..38d22fd22 100644 --- a/docs/stackit_beta_kms_key_restore.md +++ b/docs/stackit_beta_kms_key_restore.md @@ -1,28 +1,27 @@ ## stackit beta kms key restore -Resotre a key +Restore a key ### Synopsis Restores the given key from being deleted. ``` -stackit beta kms key restore [flags] +stackit beta kms key restore KEY_ID [flags] ``` ### Examples ``` Restore a KMS key "my-key-id" inside the key ring "my-key-ring-id" that was scheduled for deletion. - $ stackit beta kms keyring restore --key-ring "my-key-ring-id" --key "my-key-id" + $ stackit beta kms keyring restore "my-key-id" --key-ring "my-key-ring-id" ``` ### Options ``` - -h, --help Help for "stackit beta kms key restore" - --key string ID of the actual Key - --key-ring string ID of the KMS Key Ring where the Key is stored + -h, --help Help for "stackit beta kms key restore" + --key-ring-id string ID of the KMS Key Ring where the Key is stored ``` ### Options inherited from parent commands diff --git a/docs/stackit_beta_kms_key_rotate.md b/docs/stackit_beta_kms_key_rotate.md index 05beab716..18b0ac144 100644 --- a/docs/stackit_beta_kms_key_rotate.md +++ b/docs/stackit_beta_kms_key_rotate.md @@ -7,22 +7,21 @@ Rotate a key Rotates the given key. ``` -stackit beta kms key rotate [flags] +stackit beta kms key rotate KEY_ID [flags] ``` ### Examples ``` Rotate a KMS key "my-key-id" and increase it's version inside the key ring "my-key-ring-id". - $ stackit beta kms key rotate --key-ring "my-key-ring-id" --key "my-key-id" + $ stackit beta kms key rotate "my-key-id" --key-ring "my-key-ring-id" ``` ### Options ``` - -h, --help Help for "stackit beta kms key rotate" - --key string ID of the actual key - --key-ring string ID of the KMS key Ring where the key is stored + -h, --help Help for "stackit beta kms key rotate" + --key-ring-id string ID of the KMS key Ring where the key is stored ``` ### Options inherited from parent commands diff --git a/docs/stackit_beta_kms_keyring_create.md b/docs/stackit_beta_kms_keyring_create.md index 0cd309c3a..bd1565d3d 100644 --- a/docs/stackit_beta_kms_keyring_create.md +++ b/docs/stackit_beta_kms_keyring_create.md @@ -14,10 +14,10 @@ stackit beta kms keyring create [flags] ``` Create a KMS key ring - $ stakit beta kms keyring create --name my-keyring + $ stackit beta kms keyring create --name my-keyring Create a KMS key ring with a description - $ stakit beta kms keyring create --name my-keyring --description my-description + $ stackit beta kms keyring create --name my-keyring --description my-description ``` ### Options diff --git a/docs/stackit_beta_kms_keyring_delete.md b/docs/stackit_beta_kms_keyring_delete.md index b3ed9c805..668cf8341 100644 --- a/docs/stackit_beta_kms_keyring_delete.md +++ b/docs/stackit_beta_kms_keyring_delete.md @@ -13,8 +13,8 @@ stackit beta kms keyring delete KEYRING_ID [flags] ### Examples ``` - Delete a KMS key ring with ID "xxx" - $ stackit beta kms keyring delete xxx + Delete a KMS key ring with ID "my-key-ring-id" + $ stackit beta kms keyring delete "my-key-ring-id" ``` ### Options diff --git a/docs/stackit_beta_kms_version_destroy.md b/docs/stackit_beta_kms_version_destroy.md index d6780f42b..31ec8e56b 100644 --- a/docs/stackit_beta_kms_version_destroy.md +++ b/docs/stackit_beta_kms_version_destroy.md @@ -7,23 +7,22 @@ Destroy a key version Removes the key material of a version. ``` -stackit beta kms version destroy [flags] +stackit beta kms version destroy VERSION_NUMBER [flags] ``` ### Examples ``` - Destroy key version "0" for the key "my-key-id" inside the key ring "my-key-ring-id" - $ stackit beta kms version destroy --key "my-key-id" --key-ring "my-key-ring-id" --version 0 + Destroy key version "42" for the key "my-key-id" inside the key ring "my-key-ring-id" + $ stackit beta kms version destroy 42 --key "my-key-id" --key-ring "my-key-ring-id" ``` ### Options ``` - -h, --help Help for "stackit beta kms version destroy" - --key string ID of the key - --key-ring string ID of the KMS key ring - --version int Version number of the key + -h, --help Help for "stackit beta kms version destroy" + --key-id string ID of the key + --key-ring-id string ID of the KMS key ring ``` ### Options inherited from parent commands diff --git a/docs/stackit_beta_kms_version_disable.md b/docs/stackit_beta_kms_version_disable.md index 43ce36815..51a07c1af 100644 --- a/docs/stackit_beta_kms_version_disable.md +++ b/docs/stackit_beta_kms_version_disable.md @@ -7,23 +7,22 @@ Disable a key version Disable the given key version. ``` -stackit beta kms version disable [flags] +stackit beta kms version disable VERSION_NUMBER [flags] ``` ### Examples ``` - Disable key version "0" for the key "my-key-id" inside the key ring "my-key-ring-id" - $ stackit beta kms version disable --key "my-key-id" --key-ring "my-key-ring-id" --version 0 + Disable key version "42" for the key "my-key-id" inside the key ring "my-key-ring-id" + $ stackit beta kms version disable 42 --key "my-key-id" --key-ring "my-key-ring-id" ``` ### Options ``` - -h, --help Help for "stackit beta kms version disable" - --key string ID of the rey - --key-ring string ID of the KMS key ring - --version int Version number of the key + -h, --help Help for "stackit beta kms version disable" + --key-id string ID of the rey + --key-ring-id string ID of the KMS key ring ``` ### Options inherited from parent commands diff --git a/docs/stackit_beta_kms_version_enable.md b/docs/stackit_beta_kms_version_enable.md index ea9ac8f82..535f61e8b 100644 --- a/docs/stackit_beta_kms_version_enable.md +++ b/docs/stackit_beta_kms_version_enable.md @@ -7,23 +7,22 @@ Enable a key version Enable the given key version. ``` -stackit beta kms version enable [flags] +stackit beta kms version enable VERSION_NUMBER [flags] ``` ### Examples ``` - Enable key version "0" for the key "my-key-id" inside the key ring "my-key-ring-id" - $ stackit beta kms version enable --key "my-key-id" --key-ring "my-key-ring-id" --version 0 + Enable key version "42" for the key "my-key-id" inside the key ring "my-key-ring-id" + $ stackit beta kms version enable 42 --key "my-key-id" --key-ring "my-key-ring-id" ``` ### Options ``` - -h, --help Help for "stackit beta kms version enable" - --key string ID of the key - --key-ring string ID of the KMS key ring - --version int Version number of the key + -h, --help Help for "stackit beta kms version enable" + --key-id string ID of the key + --key-ring-id string ID of the KMS key ring ``` ### Options inherited from parent commands diff --git a/docs/stackit_beta_kms_version_list.md b/docs/stackit_beta_kms_version_list.md index e5fd68e0e..2e4311bc7 100644 --- a/docs/stackit_beta_kms_version_list.md +++ b/docs/stackit_beta_kms_version_list.md @@ -23,9 +23,9 @@ stackit beta kms version list [flags] ### Options ``` - -h, --help Help for "stackit beta kms version list" - --key string ID of the key - --key-ring string ID of the KMS key ring + -h, --help Help for "stackit beta kms version list" + --key-id string ID of the key + --key-ring-id string ID of the KMS key ring ``` ### Options inherited from parent commands diff --git a/docs/stackit_beta_kms_version_restore.md b/docs/stackit_beta_kms_version_restore.md index a6d8a7548..3dc8ad525 100644 --- a/docs/stackit_beta_kms_version_restore.md +++ b/docs/stackit_beta_kms_version_restore.md @@ -7,23 +7,22 @@ Restore a key version Restores the specified version of key. ``` -stackit beta kms version restore [flags] +stackit beta kms version restore VERSION_NUMBER [flags] ``` ### Examples ``` - Restore key version "0" for the key "my-key-id" inside the key ring "my-key-ring-id" - $ stackit beta kms version restore --key "my-key-id" --key-ring "my-key-ring-id" --version 0 + Restore key version "42" for the key "my-key-id" inside the key ring "my-key-ring-id" + $ stackit beta kms version restore 42 --key "my-key-id" --key-ring "my-key-ring-id" ``` ### Options ``` - -h, --help Help for "stackit beta kms version restore" - --key string ID of the key - --key-ring string ID of the KMS key ring - --version int Version number of the key + -h, --help Help for "stackit beta kms version restore" + --key-id string ID of the key + --key-ring-id string ID of the KMS key ring ``` ### Options inherited from parent commands diff --git a/docs/stackit_beta_kms_wrapping-key.md b/docs/stackit_beta_kms_wrapping-key.md index 8a2728867..320d8e6af 100644 --- a/docs/stackit_beta_kms_wrapping-key.md +++ b/docs/stackit_beta_kms_wrapping-key.md @@ -32,5 +32,5 @@ stackit beta kms wrapping-key [flags] * [stackit beta kms](./stackit_beta_kms.md) - Provides functionality for KMS * [stackit beta kms wrapping-key create](./stackit_beta_kms_wrapping-key_create.md) - Creates a KMS wrapping key * [stackit beta kms wrapping-key delete](./stackit_beta_kms_wrapping-key_delete.md) - Deletes a KMS wrapping key -* [stackit beta kms wrapping-key list](./stackit_beta_kms_wrapping-key_list.md) - Lists all KMS Wrapping Keys +* [stackit beta kms wrapping-key list](./stackit_beta_kms_wrapping-key_list.md) - Lists all KMS wrapping keys diff --git a/docs/stackit_beta_kms_wrapping-key_create.md b/docs/stackit_beta_kms_wrapping-key_create.md index addafc936..74e21c0fe 100644 --- a/docs/stackit_beta_kms_wrapping-key_create.md +++ b/docs/stackit_beta_kms_wrapping-key_create.md @@ -14,10 +14,10 @@ stackit beta kms wrapping-key create [flags] ``` Create a Symmetric KMS wrapping key - $ stakit beta kms wrappingkey create --key-ring "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-wrapping-key-name" --purpose "wrap_symmetric_key" + $ stackit beta kms wrappingkey create --key-ring "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-wrapping-key-name" --purpose "wrap_symmetric_key" --protection "software" Create an Asymmetric KMS wrapping key with a description - $ stakit beta kms wrappingkey create --key-ring "my-keyring-id" --algorithm "hmac_sha256" --name "my-wrapping-key-name" --description "my-description" --purpose "wrap_asymmetric_key" + $ stackit beta kms wrappingkey create --key-ring "my-keyring-id" --algorithm "hmac_sha256" --name "my-wrapping-key-name" --description "my-description" --purpose "wrap_asymmetric_key" --protection "software" ``` ### Options @@ -26,8 +26,9 @@ stackit beta kms wrapping-key create [flags] --algorithm string En-/Decryption algorithm --description string Optional description of the wrapping key -h, --help Help for "stackit beta kms wrapping-key create" - --key-ring string ID of the KMS key ring + --key-ring-id string ID of the KMS key ring --name string The display name to distinguish multiple wrapping keys + --protection string Protection of the wrapping key. Value: 'software' --purpose string Purpose of the wrapping key. Enum: 'wrap_symmetric_key', 'wrap_asymmetric_key' ``` diff --git a/docs/stackit_beta_kms_wrapping-key_delete.md b/docs/stackit_beta_kms_wrapping-key_delete.md index 9695006e5..fee15205e 100644 --- a/docs/stackit_beta_kms_wrapping-key_delete.md +++ b/docs/stackit_beta_kms_wrapping-key_delete.md @@ -7,22 +7,21 @@ Deletes a KMS wrapping key Deletes a KMS wrapping key inside a specific key ring. ``` -stackit beta kms wrapping-key delete [flags] +stackit beta kms wrapping-key delete WRAPPING_KEY_ID [flags] ``` ### Examples ``` Delete a KMS wrapping key "my-wrapping-key-id" inside the key ring "my-key-ring-id" - $ stackit beta kms keyring delete --key-ring "my-key-ring-id" --wrapping-key "my-wrapping-key-id" + $ stackit beta kms keyring delete "my-wrapping-key-id" --key-ring "my-key-ring-id" ``` ### Options ``` - -h, --help Help for "stackit beta kms wrapping-key delete" - --key-ring string ID of the KMS key ring where the wrapping key is stored - --wrapping-key string ID of the actual wrapping key + -h, --help Help for "stackit beta kms wrapping-key delete" + --key-ring-id string ID of the KMS key ring where the wrapping key is stored ``` ### Options inherited from parent commands diff --git a/docs/stackit_beta_kms_wrapping-key_list.md b/docs/stackit_beta_kms_wrapping-key_list.md index 16a6b50a6..ab4cdbc4c 100644 --- a/docs/stackit_beta_kms_wrapping-key_list.md +++ b/docs/stackit_beta_kms_wrapping-key_list.md @@ -1,29 +1,30 @@ ## stackit beta kms wrapping-key list -Lists all KMS Wrapping Keys +Lists all KMS wrapping keys ### Synopsis -Lists all KMS Wrapping Keys inside a key ring. +Lists all KMS wrapping keys inside a key ring. ``` -stackit beta kms wrapping-key list KEYRING_ID [flags] +stackit beta kms wrapping-key list [flags] ``` ### Examples ``` - List all KMS Wrapping Keys for the key ring "xxx" - $ stackit beta kms wrappingkeys list xxx + List all KMS wrapping keys for the key ring "my-key-ring-id" + $ stackit beta kms wrappingkeys list --key-ring "my-key-ring-id" - List all KMS Wrapping Keys in JSON format - $ stackit beta kms wrappingkeys list xxx --output-format json + List all KMS wrapping keys in JSON format + $ stackit beta kms wrappingkeys list --key-ring "my-key-ring-id" --output-format json ``` ### Options ``` - -h, --help Help for "stackit beta kms wrapping-key list" + -h, --help Help for "stackit beta kms wrapping-key list" + --key-ring-id string ID of the KMS Key Ring where the Key is stored ``` ### Options inherited from parent commands From 6dd4e612cb165496cb7d73bce1f4b99538a29f30 Mon Sep 17 00:00:00 2001 From: Jan Sternagel Date: Tue, 7 Oct 2025 16:29:58 +0200 Subject: [PATCH 28/52] Added the 'nil response' test case for the outputResult() --- internal/cmd/beta/kms/key/delete/delete_test.go | 5 +++++ internal/cmd/beta/kms/key/list/list.go | 4 ++++ internal/cmd/beta/kms/key/list/list_test.go | 9 +++++++-- internal/cmd/beta/kms/key/restore/restore_test.go | 5 +++++ internal/cmd/beta/kms/keyring/delete/delete_test.go | 5 +++++ internal/cmd/beta/kms/keyring/list/list.go | 4 ++++ internal/cmd/beta/kms/keyring/list/list_test.go | 7 +++++++ internal/cmd/beta/kms/version/destroy/destroy_test.go | 5 +++++ internal/cmd/beta/kms/version/disable/disable_test.go | 5 +++++ internal/cmd/beta/kms/version/enable/enable_test.go | 5 +++++ internal/cmd/beta/kms/version/restore/restore_test.go | 5 +++++ internal/cmd/beta/kms/wrappingkey/list/list.go | 4 ++++ internal/cmd/beta/kms/wrappingkey/list/list_test.go | 6 ++++++ 13 files changed, 67 insertions(+), 2 deletions(-) diff --git a/internal/cmd/beta/kms/key/delete/delete_test.go b/internal/cmd/beta/kms/key/delete/delete_test.go index a3fd66425..b073b45be 100644 --- a/internal/cmd/beta/kms/key/delete/delete_test.go +++ b/internal/cmd/beta/kms/key/delete/delete_test.go @@ -255,6 +255,11 @@ func TestOutputResult(t *testing.T) { outputFormat string resp *kms.Key }{ + { + description: "nil response", + resp: nil, + wantErr: true, + }, { description: "default output", resp: &kms.Key{}, diff --git a/internal/cmd/beta/kms/key/list/list.go b/internal/cmd/beta/kms/key/list/list.go index d1f3a841f..be247635f 100644 --- a/internal/cmd/beta/kms/key/list/list.go +++ b/internal/cmd/beta/kms/key/list/list.go @@ -106,6 +106,10 @@ func configureFlags(cmd *cobra.Command) { } func outputResult(p *print.Printer, outputFormat, projectId, keyRingId string, keys []kms.Key) error { + if keys == nil { + return fmt.Errorf("response was an empty list") + } + switch outputFormat { case print.JSONOutputFormat: details, err := json.MarshalIndent(keys, "", " ") diff --git a/internal/cmd/beta/kms/key/list/list_test.go b/internal/cmd/beta/kms/key/list/list_test.go index 49e1aa000..6092c9f08 100644 --- a/internal/cmd/beta/kms/key/list/list_test.go +++ b/internal/cmd/beta/kms/key/list/list_test.go @@ -206,8 +206,13 @@ func TestOutputResult(t *testing.T) { outputFormat string wantErr bool }{ - // Response check was moved inside NewCmd() for better error feedback. - // Thus, no check for 'keys = nil' needed + { + description: "nil response", + keys: nil, + projectId: uuid.NewString(), + keyRingId: uuid.NewString(), + wantErr: true, + }, { description: "default output", keys: []kms.Key{}, diff --git a/internal/cmd/beta/kms/key/restore/restore_test.go b/internal/cmd/beta/kms/key/restore/restore_test.go index b9af8a63a..69860461d 100644 --- a/internal/cmd/beta/kms/key/restore/restore_test.go +++ b/internal/cmd/beta/kms/key/restore/restore_test.go @@ -255,6 +255,11 @@ func TestOutputResult(t *testing.T) { outputFormat string resp *kms.Key }{ + { + description: "nil response", + resp: nil, + wantErr: true, + }, { description: "default output", resp: &kms.Key{}, diff --git a/internal/cmd/beta/kms/keyring/delete/delete_test.go b/internal/cmd/beta/kms/keyring/delete/delete_test.go index c8b4a6e3b..90cd99ad5 100644 --- a/internal/cmd/beta/kms/keyring/delete/delete_test.go +++ b/internal/cmd/beta/kms/keyring/delete/delete_test.go @@ -218,6 +218,11 @@ func TestOutputResult(t *testing.T) { outputFormat string resp *kms.KeyRing }{ + { + description: "nil response", + resp: nil, + wantErr: true, + }, { description: "default output", resp: &kms.KeyRing{}, diff --git a/internal/cmd/beta/kms/keyring/list/list.go b/internal/cmd/beta/kms/keyring/list/list.go index 531c826b0..deadb817e 100644 --- a/internal/cmd/beta/kms/keyring/list/list.go +++ b/internal/cmd/beta/kms/keyring/list/list.go @@ -92,6 +92,10 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClie } func outputResult(p *print.Printer, outputFormat, projectId string, keyRings []kms.KeyRing) error { + if keyRings == nil { + return fmt.Errorf("response was nil") + } + switch outputFormat { case print.JSONOutputFormat: details, err := json.MarshalIndent(keyRings, "", " ") diff --git a/internal/cmd/beta/kms/keyring/list/list_test.go b/internal/cmd/beta/kms/keyring/list/list_test.go index ca8bdcfe9..ee03e73e7 100644 --- a/internal/cmd/beta/kms/keyring/list/list_test.go +++ b/internal/cmd/beta/kms/keyring/list/list_test.go @@ -179,6 +179,13 @@ func TestOutputResult(t *testing.T) { projectLabel string wantErr bool }{ + { + description: "nil response", + keyRings: nil, + projectId: uuid.NewString(), + projectLabel: "my-project", + wantErr: true, + }, { description: "default output", projectId: uuid.NewString(), diff --git a/internal/cmd/beta/kms/version/destroy/destroy_test.go b/internal/cmd/beta/kms/version/destroy/destroy_test.go index b407f3a8b..898d1a084 100644 --- a/internal/cmd/beta/kms/version/destroy/destroy_test.go +++ b/internal/cmd/beta/kms/version/destroy/destroy_test.go @@ -283,6 +283,11 @@ func TestOutputResult(t *testing.T) { outputFormat string resp *kms.Version }{ + { + description: "nil response", + resp: nil, + wantErr: true, + }, { description: "default output", resp: &kms.Version{}, diff --git a/internal/cmd/beta/kms/version/disable/disable_test.go b/internal/cmd/beta/kms/version/disable/disable_test.go index 571e791f1..66ec302b8 100644 --- a/internal/cmd/beta/kms/version/disable/disable_test.go +++ b/internal/cmd/beta/kms/version/disable/disable_test.go @@ -283,6 +283,11 @@ func TestOutputResult(t *testing.T) { outputFormat string resp *kms.Version }{ + { + description: "nil response", + resp: nil, + wantErr: true, + }, { description: "default output", resp: &kms.Version{}, diff --git a/internal/cmd/beta/kms/version/enable/enable_test.go b/internal/cmd/beta/kms/version/enable/enable_test.go index bff55f829..381f7885a 100644 --- a/internal/cmd/beta/kms/version/enable/enable_test.go +++ b/internal/cmd/beta/kms/version/enable/enable_test.go @@ -283,6 +283,11 @@ func TestOutputResult(t *testing.T) { outputFormat string resp *kms.Version }{ + { + description: "nil response", + resp: nil, + wantErr: true, + }, { description: "default output", resp: &kms.Version{}, diff --git a/internal/cmd/beta/kms/version/restore/restore_test.go b/internal/cmd/beta/kms/version/restore/restore_test.go index 3fefc6f81..ad388135e 100644 --- a/internal/cmd/beta/kms/version/restore/restore_test.go +++ b/internal/cmd/beta/kms/version/restore/restore_test.go @@ -283,6 +283,11 @@ func TestOutputResult(t *testing.T) { outputFormat string resp *kms.Version }{ + { + description: "nil response", + resp: nil, + wantErr: true, + }, { description: "default output", resp: &kms.Version{}, diff --git a/internal/cmd/beta/kms/wrappingkey/list/list.go b/internal/cmd/beta/kms/wrappingkey/list/list.go index 8f0deb386..187484884 100644 --- a/internal/cmd/beta/kms/wrappingkey/list/list.go +++ b/internal/cmd/beta/kms/wrappingkey/list/list.go @@ -106,6 +106,10 @@ func configureFlags(cmd *cobra.Command) { } func outputResult(p *print.Printer, outputFormat, keyRingId string, wrappingKeys []kms.WrappingKey) error { + if wrappingKeys == nil { + return fmt.Errorf("response was nil") + } + switch outputFormat { case print.JSONOutputFormat: details, err := json.MarshalIndent(wrappingKeys, "", " ") diff --git a/internal/cmd/beta/kms/wrappingkey/list/list_test.go b/internal/cmd/beta/kms/wrappingkey/list/list_test.go index 10caf83d1..233e0bc0e 100644 --- a/internal/cmd/beta/kms/wrappingkey/list/list_test.go +++ b/internal/cmd/beta/kms/wrappingkey/list/list_test.go @@ -211,6 +211,12 @@ func TestOutputResult(t *testing.T) { projectLabel string wantErr bool }{ + { + description: "nil response", + wrappingKeys: nil, + projectLabel: "my-project", + wantErr: true, + }, { description: "default output", wrappingKeys: []kms.WrappingKey{}, From e7c6c719de43e03ca559c4f72135bf184f457c3b Mon Sep 17 00:00:00 2001 From: JanStern <65732422+JanStern@users.noreply.github.com> Date: Wed, 8 Oct 2025 09:46:22 +0200 Subject: [PATCH 29/52] Update internal/cmd/beta/kms/key/delete/delete.go MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit You are absolutely right! Co-authored-by: Ruben Hönle --- internal/cmd/beta/kms/key/delete/delete.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/cmd/beta/kms/key/delete/delete.go b/internal/cmd/beta/kms/key/delete/delete.go index d5254c4ca..97016191f 100644 --- a/internal/cmd/beta/kms/key/delete/delete.go +++ b/internal/cmd/beta/kms/key/delete/delete.go @@ -42,7 +42,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Example: examples.Build( examples.NewExample( `Delete a KMS key "my-key-id" inside the key ring "my-key-ring-id"`, - `$ stackit beta kms keyring delete "my-key-id" --key-ring "my-key-ring-id"`), + `$ stackit beta kms key delete "my-key-id" --key-ring "my-key-ring-id"`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() From ff4b53aaeda040da92a66eaf6d0268cc1d5deee2 Mon Sep 17 00:00:00 2001 From: JanStern <65732422+JanStern@users.noreply.github.com> Date: Wed, 8 Oct 2025 10:06:07 +0200 Subject: [PATCH 30/52] Update internal/cmd/beta/kms/wrappingkey/create/create.go MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Ruben Hönle --- internal/cmd/beta/kms/wrappingkey/create/create.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/cmd/beta/kms/wrappingkey/create/create.go b/internal/cmd/beta/kms/wrappingkey/create/create.go index e70220887..4b39d0325 100644 --- a/internal/cmd/beta/kms/wrappingkey/create/create.go +++ b/internal/cmd/beta/kms/wrappingkey/create/create.go @@ -56,7 +56,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { `$ stackit beta kms wrappingkey create --key-ring "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-wrapping-key-name" --purpose "wrap_symmetric_key" --protection "software"`), examples.NewExample( `Create an Asymmetric KMS wrapping key with a description`, - `$ stackit beta kms wrappingkey create --key-ring "my-keyring-id" --algorithm "hmac_sha256" --name "my-wrapping-key-name" --description "my-description" --purpose "wrap_asymmetric_key" --protection "software"`), + `$ stackit beta kms wrapping-key create --key-ring "my-keyring-id" --algorithm "hmac_sha256" --name "my-wrapping-key-name" --description "my-description" --purpose "wrap_asymmetric_key" --protection "software"`), ), RunE: func(cmd *cobra.Command, _ []string) error { ctx := context.Background() From e9d3719e04f5cb732886140ca54d3583fb2c241e Mon Sep 17 00:00:00 2001 From: JanStern <65732422+JanStern@users.noreply.github.com> Date: Wed, 8 Oct 2025 10:06:24 +0200 Subject: [PATCH 31/52] Update internal/cmd/beta/kms/wrappingkey/wrappingkey.go MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Ruben Hönle --- internal/cmd/beta/kms/wrappingkey/wrappingkey.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/cmd/beta/kms/wrappingkey/wrappingkey.go b/internal/cmd/beta/kms/wrappingkey/wrappingkey.go index ab62f221d..00184a521 100644 --- a/internal/cmd/beta/kms/wrappingkey/wrappingkey.go +++ b/internal/cmd/beta/kms/wrappingkey/wrappingkey.go @@ -15,7 +15,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { cmd := &cobra.Command{ Use: "wrapping-key", Short: "Manage KMS wrapping keys", - Long: "Provides CRUD functionality for wrapping key operations inside the KMS", + Long: "Provides functionality for wrapping key operations inside the KMS", Args: args.NoArgs, Run: utils.CmdHelp, } From c19a855b25c7d35a00c5f57c84d1c01c07e37777 Mon Sep 17 00:00:00 2001 From: JanStern <65732422+JanStern@users.noreply.github.com> Date: Wed, 8 Oct 2025 10:06:42 +0200 Subject: [PATCH 32/52] Update internal/cmd/beta/kms/wrappingkey/create/create.go MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Ruben Hönle --- internal/cmd/beta/kms/wrappingkey/create/create.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/cmd/beta/kms/wrappingkey/create/create.go b/internal/cmd/beta/kms/wrappingkey/create/create.go index 4b39d0325..7d41a5514 100644 --- a/internal/cmd/beta/kms/wrappingkey/create/create.go +++ b/internal/cmd/beta/kms/wrappingkey/create/create.go @@ -53,7 +53,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Example: examples.Build( examples.NewExample( `Create a Symmetric KMS wrapping key`, - `$ stackit beta kms wrappingkey create --key-ring "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-wrapping-key-name" --purpose "wrap_symmetric_key" --protection "software"`), + `$ stackit beta kms wrapping-key create --key-ring "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-wrapping-key-name" --purpose "wrap_symmetric_key" --protection "software"`), examples.NewExample( `Create an Asymmetric KMS wrapping key with a description`, `$ stackit beta kms wrapping-key create --key-ring "my-keyring-id" --algorithm "hmac_sha256" --name "my-wrapping-key-name" --description "my-description" --purpose "wrap_asymmetric_key" --protection "software"`), From fe097713740d9141296b7efbf0e1b5dafd1a6b12 Mon Sep 17 00:00:00 2001 From: JanStern <65732422+JanStern@users.noreply.github.com> Date: Wed, 8 Oct 2025 10:06:54 +0200 Subject: [PATCH 33/52] Update internal/cmd/beta/kms/wrappingkey/delete/delete.go MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Ruben Hönle --- internal/cmd/beta/kms/wrappingkey/delete/delete.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/cmd/beta/kms/wrappingkey/delete/delete.go b/internal/cmd/beta/kms/wrappingkey/delete/delete.go index 13a21eedc..495e0f9d5 100644 --- a/internal/cmd/beta/kms/wrappingkey/delete/delete.go +++ b/internal/cmd/beta/kms/wrappingkey/delete/delete.go @@ -40,7 +40,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Example: examples.Build( examples.NewExample( `Delete a KMS wrapping key "my-wrapping-key-id" inside the key ring "my-key-ring-id"`, - `$ stackit beta kms keyring delete "my-wrapping-key-id" --key-ring "my-key-ring-id"`), + `$ stackit beta kms wrapping-key delete "my-wrapping-key-id" --key-ring "my-key-ring-id"`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() From 0852adacf572c46cbb3554e5321a2510db44cec2 Mon Sep 17 00:00:00 2001 From: JanStern <65732422+JanStern@users.noreply.github.com> Date: Wed, 8 Oct 2025 10:07:20 +0200 Subject: [PATCH 34/52] Update internal/cmd/beta/kms/wrappingkey/list/list.go MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Ruben Hönle --- internal/cmd/beta/kms/wrappingkey/list/list.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/cmd/beta/kms/wrappingkey/list/list.go b/internal/cmd/beta/kms/wrappingkey/list/list.go index 187484884..29894067a 100644 --- a/internal/cmd/beta/kms/wrappingkey/list/list.go +++ b/internal/cmd/beta/kms/wrappingkey/list/list.go @@ -38,7 +38,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Example: examples.Build( examples.NewExample( `List all KMS wrapping keys for the key ring "my-key-ring-id"`, - `$ stackit beta kms wrappingkeys list --key-ring "my-key-ring-id"`), + `$ stackit beta kms wrapping-key list --key-ring "my-key-ring-id"`), examples.NewExample( `List all KMS wrapping keys in JSON format`, `$ stackit beta kms wrappingkeys list --key-ring "my-key-ring-id" --output-format json`), From 78871c2e8935b1793719b27eff72991916d683e5 Mon Sep 17 00:00:00 2001 From: Jan Sternagel Date: Thu, 9 Oct 2025 11:00:46 +0200 Subject: [PATCH 35/52] removed risky delete output --- .../cmd/beta/kms/keyring/delete/delete.go | 36 ++-------------- .../beta/kms/keyring/delete/delete_test.go | 43 ------------------- 2 files changed, 3 insertions(+), 76 deletions(-) diff --git a/internal/cmd/beta/kms/keyring/delete/delete.go b/internal/cmd/beta/kms/keyring/delete/delete.go index e089fc8c4..b22a1d372 100644 --- a/internal/cmd/beta/kms/keyring/delete/delete.go +++ b/internal/cmd/beta/kms/keyring/delete/delete.go @@ -2,10 +2,8 @@ package delete import ( "context" - "encoding/json" "fmt" - "github.com/goccy/go-yaml" "github.com/spf13/cobra" "github.com/stackitcloud/stackit-cli/internal/cmd/params" "github.com/stackitcloud/stackit-cli/internal/pkg/args" @@ -76,12 +74,9 @@ func NewCmd(params *params.CmdParams) *cobra.Command { // Wait for async operation not relevant. Key ring deletion is synchronous. - // Get the key ring so it can be outputted in the state it is after the deletion. - resp, err := apiClient.GetKeyRingExecute(ctx, model.ProjectId, model.Region, model.KeyRingId) - if err != nil { - params.Printer.Debug(print.ErrorLevel, "get KMS Key Ring: %w", err) - } - return outputResult(params.Printer, model.OutputFormat, resp) + // Don't output anything. It's a deletion. + params.Printer.Info("Deleted the key ring %q\n", keyRingLabel) + return nil }, } return cmd @@ -116,28 +111,3 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClie req := apiClient.DeleteKeyRing(ctx, model.ProjectId, model.Region, model.KeyRingId) return req } - -func outputResult(p *print.Printer, outputFormat string, resp *kms.KeyRing) error { - if resp == nil { - return fmt.Errorf("response from 'GetKeyExecute()' is nil") - } - - switch outputFormat { - case print.JSONOutputFormat: - details, err := json.MarshalIndent(resp, "", " ") - if err != nil { - return fmt.Errorf("marshal output to JSON: %w", err) - } - p.Outputln(string(details)) - case print.YAMLOutputFormat: - details, err := yaml.MarshalWithOptions(resp, yaml.IndentSequence(true), yaml.UseJSONMarshaler()) - if err != nil { - return fmt.Errorf("marshal output to YAML: %w", err) - } - p.Outputln(string(details)) - - default: - p.Outputf("Deleted key ring: %s\n", utils.PtrString(resp.DisplayName)) - } - return nil -} diff --git a/internal/cmd/beta/kms/keyring/delete/delete_test.go b/internal/cmd/beta/kms/keyring/delete/delete_test.go index 90cd99ad5..c53e7d7f0 100644 --- a/internal/cmd/beta/kms/keyring/delete/delete_test.go +++ b/internal/cmd/beta/kms/keyring/delete/delete_test.go @@ -210,46 +210,3 @@ func TestBuildRequest(t *testing.T) { }) } } - -func TestOutputResult(t *testing.T) { - tests := []struct { - description string - wantErr bool - outputFormat string - resp *kms.KeyRing - }{ - { - description: "nil response", - resp: nil, - wantErr: true, - }, - { - description: "default output", - resp: &kms.KeyRing{}, - wantErr: false, - }, - { - description: "json output", - outputFormat: print.JSONOutputFormat, - resp: &kms.KeyRing{}, - wantErr: false, - }, - { - description: "yaml output", - outputFormat: print.YAMLOutputFormat, - resp: &kms.KeyRing{}, - wantErr: false, - }, - } - - p := print.NewPrinter() - p.Cmd = NewCmd(¶ms.CmdParams{Printer: p}) - for _, tt := range tests { - t.Run(tt.description, func(t *testing.T) { - err := outputResult(p, tt.outputFormat, tt.resp) - if (err != nil) != tt.wantErr { - t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr) - } - }) - } -} From 6639d4e4612f24efce2f9adde7cd46797d901d5f Mon Sep 17 00:00:00 2001 From: Jan Sternagel Date: Thu, 9 Oct 2025 12:58:34 +0200 Subject: [PATCH 36/52] addressing nil pointer derferences --- internal/cmd/beta/kms/key/create/create.go | 6 +++--- internal/cmd/beta/kms/key/delete/delete.go | 2 +- .../cmd/beta/kms/key/importKey/importKey.go | 4 ++-- internal/cmd/beta/kms/key/list/list.go | 10 ++++++---- internal/cmd/beta/kms/key/list/list_test.go | 19 ++++++++++++------ internal/cmd/beta/kms/key/restore/restore.go | 2 +- internal/cmd/beta/kms/keyring/list/list.go | 10 ++++++---- .../cmd/beta/kms/keyring/list/list_test.go | 19 ++++++++++++------ internal/cmd/beta/kms/version/list/list.go | 12 +++++++---- .../cmd/beta/kms/version/list/list_test.go | 20 ++++++++++++------- .../cmd/beta/kms/version/restore/restore.go | 2 +- .../cmd/beta/kms/wrappingkey/list/list.go | 11 +++++----- .../beta/kms/wrappingkey/list/list_test.go | 12 +++++------ internal/pkg/services/kms/utils/utils.go | 20 +++++++++++++++++++ 14 files changed, 99 insertions(+), 50 deletions(-) diff --git a/internal/cmd/beta/kms/key/create/create.go b/internal/cmd/beta/kms/key/create/create.go index abea08588..92efb8b46 100644 --- a/internal/cmd/beta/kms/key/create/create.go +++ b/internal/cmd/beta/kms/key/create/create.go @@ -89,7 +89,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { // Call API req, _ := buildRequest(ctx, model, apiClient) - key, err := req.Execute() + resp, err := req.Execute() if err != nil { return fmt.Errorf("create KMS key: %w", err) } @@ -98,14 +98,14 @@ func NewCmd(params *params.CmdParams) *cobra.Command { if !model.Async { s := spinner.New(params.Printer) s.Start("Creating key") - _, err = wait.CreateOrUpdateKeyWaitHandler(ctx, apiClient, model.ProjectId, model.Region, model.KeyRingId, *key.Id).WaitWithContext(ctx) + _, err = wait.CreateOrUpdateKeyWaitHandler(ctx, apiClient, model.ProjectId, model.Region, model.KeyRingId, *resp.Id).WaitWithContext(ctx) if err != nil { return fmt.Errorf("wait for KMS key creation: %w", err) } s.Stop() } - return outputResult(params.Printer, model.OutputFormat, projectLabel, key) + return outputResult(params.Printer, model.OutputFormat, projectLabel, resp) }, } configureFlags(cmd) diff --git a/internal/cmd/beta/kms/key/delete/delete.go b/internal/cmd/beta/kms/key/delete/delete.go index 97016191f..bfcf35748 100644 --- a/internal/cmd/beta/kms/key/delete/delete.go +++ b/internal/cmd/beta/kms/key/delete/delete.go @@ -132,7 +132,7 @@ func configureFlags(cmd *cobra.Command) { func outputResult(p *print.Printer, outputFormat string, resp *kms.Key) error { if resp == nil { - return fmt.Errorf("response from 'GetKeyExecute()' is nil") + return fmt.Errorf("response is nil") } switch outputFormat { diff --git a/internal/cmd/beta/kms/key/importKey/importKey.go b/internal/cmd/beta/kms/key/importKey/importKey.go index 2097c3e68..947194c77 100644 --- a/internal/cmd/beta/kms/key/importKey/importKey.go +++ b/internal/cmd/beta/kms/key/importKey/importKey.go @@ -83,12 +83,12 @@ func NewCmd(params *params.CmdParams) *cobra.Command { // Call API req, _ := buildRequest(ctx, model, apiClient) - keyVersion, err := req.Execute() + resp, err := req.Execute() if err != nil { return fmt.Errorf("import KMS key: %w", err) } - return outputResult(params.Printer, model.OutputFormat, keyRingName, keyName, keyVersion) + return outputResult(params.Printer, model.OutputFormat, keyRingName, keyName, resp) }, } configureFlags(cmd) diff --git a/internal/cmd/beta/kms/key/list/list.go b/internal/cmd/beta/kms/key/list/list.go index be247635f..a511d2d7a 100644 --- a/internal/cmd/beta/kms/key/list/list.go +++ b/internal/cmd/beta/kms/key/list/list.go @@ -63,7 +63,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { return fmt.Errorf("get KMS Keys: %w", err) } - return outputResult(params.Printer, model.OutputFormat, model.ProjectId, model.KeyRingId, *resp.Keys) + return outputResult(params.Printer, model.OutputFormat, model.ProjectId, model.KeyRingId, resp) }, } @@ -105,11 +105,13 @@ func configureFlags(cmd *cobra.Command) { cobra.CheckErr(err) } -func outputResult(p *print.Printer, outputFormat, projectId, keyRingId string, keys []kms.Key) error { - if keys == nil { - return fmt.Errorf("response was an empty list") +func outputResult(p *print.Printer, outputFormat, projectId, keyRingId string, resp *kms.KeyList) error { + if resp == nil || resp.Keys == nil { + return fmt.Errorf("response was nil / empty") } + keys := *resp.Keys + switch outputFormat { case print.JSONOutputFormat: details, err := json.MarshalIndent(keys, "", " ") diff --git a/internal/cmd/beta/kms/key/list/list_test.go b/internal/cmd/beta/kms/key/list/list_test.go index 6092c9f08..17d773bd5 100644 --- a/internal/cmd/beta/kms/key/list/list_test.go +++ b/internal/cmd/beta/kms/key/list/list_test.go @@ -200,7 +200,7 @@ func TestBuildRequest(t *testing.T) { func TestOutputResult(t *testing.T) { tests := []struct { description string - keys []kms.Key + resp *kms.KeyList projectId string keyRingId string outputFormat string @@ -208,21 +208,28 @@ func TestOutputResult(t *testing.T) { }{ { description: "nil response", - keys: nil, + resp: nil, + projectId: uuid.NewString(), + keyRingId: uuid.NewString(), + wantErr: true, + }, + { + description: "empty response", + resp: &kms.KeyList{}, projectId: uuid.NewString(), keyRingId: uuid.NewString(), wantErr: true, }, { description: "default output", - keys: []kms.Key{}, + resp: &kms.KeyList{Keys: &[]kms.Key{}}, projectId: uuid.NewString(), keyRingId: uuid.NewString(), wantErr: false, }, { description: "json output", - keys: []kms.Key{}, + resp: &kms.KeyList{Keys: &[]kms.Key{}}, projectId: uuid.NewString(), keyRingId: uuid.NewString(), outputFormat: print.JSONOutputFormat, @@ -230,7 +237,7 @@ func TestOutputResult(t *testing.T) { }, { description: "yaml output", - keys: []kms.Key{}, + resp: &kms.KeyList{Keys: &[]kms.Key{}}, projectId: uuid.NewString(), keyRingId: uuid.NewString(), outputFormat: print.YAMLOutputFormat, @@ -242,7 +249,7 @@ func TestOutputResult(t *testing.T) { p.Cmd = NewCmd(¶ms.CmdParams{Printer: p}) for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { - err := outputResult(p, tt.outputFormat, tt.projectId, tt.keyRingId, tt.keys) + err := outputResult(p, tt.outputFormat, tt.projectId, tt.keyRingId, tt.resp) if (err != nil) != tt.wantErr { t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr) } diff --git a/internal/cmd/beta/kms/key/restore/restore.go b/internal/cmd/beta/kms/key/restore/restore.go index 236bda622..2e7e27af1 100644 --- a/internal/cmd/beta/kms/key/restore/restore.go +++ b/internal/cmd/beta/kms/key/restore/restore.go @@ -131,7 +131,7 @@ func configureFlags(cmd *cobra.Command) { func outputResult(p *print.Printer, outputFormat string, resp *kms.Key) error { if resp == nil { - return fmt.Errorf("response from 'GetKeyExecute()' is nil") + return fmt.Errorf("response is nil") } switch outputFormat { diff --git a/internal/cmd/beta/kms/keyring/list/list.go b/internal/cmd/beta/kms/keyring/list/list.go index deadb817e..bb642fbd3 100644 --- a/internal/cmd/beta/kms/keyring/list/list.go +++ b/internal/cmd/beta/kms/keyring/list/list.go @@ -57,7 +57,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { return fmt.Errorf("get KMS key rings: %w", err) } - return outputResult(params.Printer, model.OutputFormat, model.ProjectId, *resp.KeyRings) + return outputResult(params.Printer, model.OutputFormat, model.ProjectId, resp) }, } @@ -91,11 +91,13 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClie return req } -func outputResult(p *print.Printer, outputFormat, projectId string, keyRings []kms.KeyRing) error { - if keyRings == nil { - return fmt.Errorf("response was nil") +func outputResult(p *print.Printer, outputFormat, projectId string, resp *kms.KeyRingList) error { + if resp == nil || resp.KeyRings == nil { + return fmt.Errorf("response was nil / empty") } + keyRings := *resp.KeyRings + switch outputFormat { case print.JSONOutputFormat: details, err := json.MarshalIndent(keyRings, "", " ") diff --git a/internal/cmd/beta/kms/keyring/list/list_test.go b/internal/cmd/beta/kms/keyring/list/list_test.go index ee03e73e7..d85681c99 100644 --- a/internal/cmd/beta/kms/keyring/list/list_test.go +++ b/internal/cmd/beta/kms/keyring/list/list_test.go @@ -174,14 +174,21 @@ func TestOutputResult(t *testing.T) { tests := []struct { description string projectId string - keyRings []kms.KeyRing + resp *kms.KeyRingList outputFormat string projectLabel string wantErr bool }{ { description: "nil response", - keyRings: nil, + resp: nil, + projectId: uuid.NewString(), + projectLabel: "my-project", + wantErr: true, + }, + { + description: "empty response", + resp: &kms.KeyRingList{}, projectId: uuid.NewString(), projectLabel: "my-project", wantErr: true, @@ -189,21 +196,21 @@ func TestOutputResult(t *testing.T) { { description: "default output", projectId: uuid.NewString(), - keyRings: []kms.KeyRing{}, + resp: &kms.KeyRingList{KeyRings: &[]kms.KeyRing{}}, projectLabel: "my-project", wantErr: false, }, { description: "json output", projectId: uuid.NewString(), - keyRings: []kms.KeyRing{}, + resp: &kms.KeyRingList{KeyRings: &[]kms.KeyRing{}}, outputFormat: print.JSONOutputFormat, wantErr: false, }, { description: "yaml output", projectId: uuid.NewString(), - keyRings: []kms.KeyRing{}, + resp: &kms.KeyRingList{KeyRings: &[]kms.KeyRing{}}, outputFormat: print.YAMLOutputFormat, wantErr: false, }, @@ -213,7 +220,7 @@ func TestOutputResult(t *testing.T) { p.Cmd = NewCmd(¶ms.CmdParams{Printer: p}) for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { - err := outputResult(p, tt.outputFormat, tt.projectId, tt.keyRings) + err := outputResult(p, tt.outputFormat, tt.projectId, tt.resp) if (err != nil) != tt.wantErr { t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr) } diff --git a/internal/cmd/beta/kms/version/list/list.go b/internal/cmd/beta/kms/version/list/list.go index abd04c084..a04753f66 100644 --- a/internal/cmd/beta/kms/version/list/list.go +++ b/internal/cmd/beta/kms/version/list/list.go @@ -65,7 +65,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { return fmt.Errorf("get key version: %w", err) } - return outputResult(params.Printer, model.OutputFormat, model.ProjectId, model.KeyId, *resp.Versions) + return outputResult(params.Printer, model.OutputFormat, model.ProjectId, model.KeyId, resp) }, } @@ -101,7 +101,12 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClie return apiClient.ListVersions(ctx, model.ProjectId, model.Region, model.KeyRingId, model.KeyId) } -func outputResult(p *print.Printer, outputFormat, projectId, keyId string, versions []kms.Version) error { +func outputResult(p *print.Printer, outputFormat, projectId, keyId string, resp *kms.VersionList) error { + if resp == nil || resp.Versions == nil { + return fmt.Errorf("response is nil / empty") + } + versions := *resp.Versions + switch outputFormat { case print.JSONOutputFormat: details, err := json.MarshalIndent(versions, "", " ") @@ -125,8 +130,7 @@ func outputResult(p *print.Printer, outputFormat, projectId, keyId string, versi table := tables.NewTable() table.SetHeader("ID", "NUMBER", "CREATED AT", "DESTROY DATE", "STATUS") - for i := range versions { - version := versions[i] + for _, version := range versions { table.AddRow( utils.PtrString(version.KeyId), utils.PtrString(version.Number), diff --git a/internal/cmd/beta/kms/version/list/list_test.go b/internal/cmd/beta/kms/version/list/list_test.go index 3f2172204..a1df169ac 100644 --- a/internal/cmd/beta/kms/version/list/list_test.go +++ b/internal/cmd/beta/kms/version/list/list_test.go @@ -232,32 +232,38 @@ func TestOutputResult(t *testing.T) { description string projectId string keyId string - versions []kms.Version + resp *kms.VersionList outputFormat string projectLabel string wantErr bool }{ + { + description: "nil response", + resp: nil, + projectLabel: "my-project", + wantErr: true, + }, { description: "empty default", - versions: nil, + resp: &kms.VersionList{}, projectLabel: "my-project", - wantErr: false, + wantErr: true, }, { description: "default output", - versions: []kms.Version{}, + resp: &kms.VersionList{Versions: &[]kms.Version{}}, projectLabel: "my-project", wantErr: false, }, { description: "json output", - versions: []kms.Version{}, + resp: &kms.VersionList{Versions: &[]kms.Version{}}, outputFormat: print.JSONOutputFormat, wantErr: false, }, { description: "yaml output", - versions: []kms.Version{}, + resp: &kms.VersionList{Versions: &[]kms.Version{}}, outputFormat: print.YAMLOutputFormat, wantErr: false, }, @@ -267,7 +273,7 @@ func TestOutputResult(t *testing.T) { p.Cmd = NewCmd(¶ms.CmdParams{Printer: p}) for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { - err := outputResult(p, tt.outputFormat, tt.projectId, tt.keyId, tt.versions) + err := outputResult(p, tt.outputFormat, tt.projectId, tt.keyId, tt.resp) if (err != nil) != tt.wantErr { t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr) } diff --git a/internal/cmd/beta/kms/version/restore/restore.go b/internal/cmd/beta/kms/version/restore/restore.go index 2f2e277ab..a0386d057 100644 --- a/internal/cmd/beta/kms/version/restore/restore.go +++ b/internal/cmd/beta/kms/version/restore/restore.go @@ -129,7 +129,7 @@ func configureFlags(cmd *cobra.Command) { func outputResult(p *print.Printer, outputFormat string, resp *kms.Version) error { if resp == nil { - return fmt.Errorf("response from 'GetKeyExecute()' is nil") + return fmt.Errorf("response is nil / empty") } switch outputFormat { diff --git a/internal/cmd/beta/kms/wrappingkey/list/list.go b/internal/cmd/beta/kms/wrappingkey/list/list.go index 29894067a..51bb07d09 100644 --- a/internal/cmd/beta/kms/wrappingkey/list/list.go +++ b/internal/cmd/beta/kms/wrappingkey/list/list.go @@ -63,7 +63,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { return fmt.Errorf("get KMS wrapping keys: %w", err) } - return outputResult(params.Printer, model.OutputFormat, model.KeyRingId, *resp.WrappingKeys) + return outputResult(params.Printer, model.OutputFormat, model.KeyRingId, resp) }, } @@ -105,11 +105,13 @@ func configureFlags(cmd *cobra.Command) { cobra.CheckErr(err) } -func outputResult(p *print.Printer, outputFormat, keyRingId string, wrappingKeys []kms.WrappingKey) error { - if wrappingKeys == nil { - return fmt.Errorf("response was nil") +func outputResult(p *print.Printer, outputFormat, keyRingId string, resp *kms.WrappingKeyList) error { + if resp == nil || resp.WrappingKeys == nil { + return fmt.Errorf("response is nil / empty") } + wrappingKeys := *resp.WrappingKeys + switch outputFormat { case print.JSONOutputFormat: details, err := json.MarshalIndent(wrappingKeys, "", " ") @@ -140,7 +142,6 @@ func outputResult(p *print.Printer, outputFormat, keyRingId string, wrappingKeys utils.PtrString(wrappingKey.DisplayName), utils.PtrString(wrappingKey.Purpose), utils.PtrString(wrappingKey.Algorithm), - // utils.PtrString(wrappingKey.CreatedAt), utils.PtrString(wrappingKey.ExpiresAt), utils.PtrString(wrappingKey.State), ) diff --git a/internal/cmd/beta/kms/wrappingkey/list/list_test.go b/internal/cmd/beta/kms/wrappingkey/list/list_test.go index 233e0bc0e..93eb4b88b 100644 --- a/internal/cmd/beta/kms/wrappingkey/list/list_test.go +++ b/internal/cmd/beta/kms/wrappingkey/list/list_test.go @@ -206,32 +206,32 @@ func TestOutputResult(t *testing.T) { tests := []struct { description string keyRingId string - wrappingKeys []kms.WrappingKey + resp *kms.WrappingKeyList outputFormat string projectLabel string wantErr bool }{ { description: "nil response", - wrappingKeys: nil, + resp: nil, projectLabel: "my-project", wantErr: true, }, { description: "default output", - wrappingKeys: []kms.WrappingKey{}, + resp: &kms.WrappingKeyList{WrappingKeys: &[]kms.WrappingKey{}}, projectLabel: "my-project", wantErr: false, }, { description: "json output", - wrappingKeys: []kms.WrappingKey{}, + resp: &kms.WrappingKeyList{WrappingKeys: &[]kms.WrappingKey{}}, outputFormat: print.JSONOutputFormat, wantErr: false, }, { description: "yaml output", - wrappingKeys: []kms.WrappingKey{}, + resp: &kms.WrappingKeyList{WrappingKeys: &[]kms.WrappingKey{}}, outputFormat: print.YAMLOutputFormat, wantErr: false, }, @@ -241,7 +241,7 @@ func TestOutputResult(t *testing.T) { p.Cmd = NewCmd(¶ms.CmdParams{Printer: p}) for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { - err := outputResult(p, tt.outputFormat, tt.keyRingId, tt.wrappingKeys) + err := outputResult(p, tt.outputFormat, tt.keyRingId, tt.resp) if (err != nil) != tt.wantErr { t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr) } diff --git a/internal/pkg/services/kms/utils/utils.go b/internal/pkg/services/kms/utils/utils.go index a3f111d8e..f1927924b 100644 --- a/internal/pkg/services/kms/utils/utils.go +++ b/internal/pkg/services/kms/utils/utils.go @@ -19,6 +19,11 @@ func GetKeyName(ctx context.Context, apiClient KMSClient, projectId, region, key if err != nil { return "", fmt.Errorf("get KMS Key: %w", err) } + + if resp == nil || resp.DisplayName == nil { + return "", fmt.Errorf("response is nil / empty") + } + return *resp.DisplayName, nil } @@ -27,6 +32,11 @@ func GetKeyDeletionDate(ctx context.Context, apiClient KMSClient, projectId, reg if err != nil { return time.Now(), fmt.Errorf("get KMS Key: %w", err) } + + if resp == nil || resp.DeletionDate == nil { + return time.Time{}, fmt.Errorf("response is nil / empty") + } + return *resp.DeletionDate, nil } @@ -35,6 +45,11 @@ func GetKeyRingName(ctx context.Context, apiClient KMSClient, projectId, id, reg if err != nil { return "", fmt.Errorf("get KMS Key Ring: %w", err) } + + if resp == nil || resp.DisplayName == nil { + return "", fmt.Errorf("response is nil / empty") + } + return *resp.DisplayName, nil } @@ -43,5 +58,10 @@ func GetWrappingKeyName(ctx context.Context, apiClient KMSClient, projectId, reg if err != nil { return "", fmt.Errorf("get KMS Wrapping Key: %w", err) } + + if resp == nil || resp.DisplayName == nil { + return "", fmt.Errorf("response is nil / empty") + } + return *resp.DisplayName, nil } From 8d3d9f580511386c3634722db1592df3fb643573 Mon Sep 17 00:00:00 2001 From: Jan Sternagel Date: Thu, 9 Oct 2025 12:59:04 +0200 Subject: [PATCH 37/52] updated docs --- docs/stackit_beta_kms_key_delete.md | 2 +- docs/stackit_beta_kms_wrapping-key.md | 2 +- docs/stackit_beta_kms_wrapping-key_create.md | 4 ++-- docs/stackit_beta_kms_wrapping-key_delete.md | 2 +- docs/stackit_beta_kms_wrapping-key_list.md | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/stackit_beta_kms_key_delete.md b/docs/stackit_beta_kms_key_delete.md index 26d7e243b..af7c6be0a 100644 --- a/docs/stackit_beta_kms_key_delete.md +++ b/docs/stackit_beta_kms_key_delete.md @@ -14,7 +14,7 @@ stackit beta kms key delete KEY_ID [flags] ``` Delete a KMS key "my-key-id" inside the key ring "my-key-ring-id" - $ stackit beta kms keyring delete "my-key-id" --key-ring "my-key-ring-id" + $ stackit beta kms key delete "my-key-id" --key-ring "my-key-ring-id" ``` ### Options diff --git a/docs/stackit_beta_kms_wrapping-key.md b/docs/stackit_beta_kms_wrapping-key.md index 320d8e6af..c10cb4946 100644 --- a/docs/stackit_beta_kms_wrapping-key.md +++ b/docs/stackit_beta_kms_wrapping-key.md @@ -4,7 +4,7 @@ Manage KMS wrapping keys ### Synopsis -Provides CRUD functionality for wrapping key operations inside the KMS +Provides functionality for wrapping key operations inside the KMS ``` stackit beta kms wrapping-key [flags] diff --git a/docs/stackit_beta_kms_wrapping-key_create.md b/docs/stackit_beta_kms_wrapping-key_create.md index 74e21c0fe..e4165c689 100644 --- a/docs/stackit_beta_kms_wrapping-key_create.md +++ b/docs/stackit_beta_kms_wrapping-key_create.md @@ -14,10 +14,10 @@ stackit beta kms wrapping-key create [flags] ``` Create a Symmetric KMS wrapping key - $ stackit beta kms wrappingkey create --key-ring "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-wrapping-key-name" --purpose "wrap_symmetric_key" --protection "software" + $ stackit beta kms wrapping-key create --key-ring "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-wrapping-key-name" --purpose "wrap_symmetric_key" --protection "software" Create an Asymmetric KMS wrapping key with a description - $ stackit beta kms wrappingkey create --key-ring "my-keyring-id" --algorithm "hmac_sha256" --name "my-wrapping-key-name" --description "my-description" --purpose "wrap_asymmetric_key" --protection "software" + $ stackit beta kms wrapping-key create --key-ring "my-keyring-id" --algorithm "hmac_sha256" --name "my-wrapping-key-name" --description "my-description" --purpose "wrap_asymmetric_key" --protection "software" ``` ### Options diff --git a/docs/stackit_beta_kms_wrapping-key_delete.md b/docs/stackit_beta_kms_wrapping-key_delete.md index fee15205e..6109cc909 100644 --- a/docs/stackit_beta_kms_wrapping-key_delete.md +++ b/docs/stackit_beta_kms_wrapping-key_delete.md @@ -14,7 +14,7 @@ stackit beta kms wrapping-key delete WRAPPING_KEY_ID [flags] ``` Delete a KMS wrapping key "my-wrapping-key-id" inside the key ring "my-key-ring-id" - $ stackit beta kms keyring delete "my-wrapping-key-id" --key-ring "my-key-ring-id" + $ stackit beta kms wrapping-key delete "my-wrapping-key-id" --key-ring "my-key-ring-id" ``` ### Options diff --git a/docs/stackit_beta_kms_wrapping-key_list.md b/docs/stackit_beta_kms_wrapping-key_list.md index ab4cdbc4c..6848d8111 100644 --- a/docs/stackit_beta_kms_wrapping-key_list.md +++ b/docs/stackit_beta_kms_wrapping-key_list.md @@ -14,7 +14,7 @@ stackit beta kms wrapping-key list [flags] ``` List all KMS wrapping keys for the key ring "my-key-ring-id" - $ stackit beta kms wrappingkeys list --key-ring "my-key-ring-id" + $ stackit beta kms wrapping-key list --key-ring "my-key-ring-id" List all KMS wrapping keys in JSON format $ stackit beta kms wrappingkeys list --key-ring "my-key-ring-id" --output-format json From 32cb3348e6e9e65f3cb712ed06b7a4de13370972 Mon Sep 17 00:00:00 2001 From: Jan Sternagel Date: Thu, 16 Oct 2025 16:01:19 +0200 Subject: [PATCH 38/52] Addressed PR #1016 --- internal/cmd/beta/kms/key/create/create.go | 10 +--------- internal/cmd/beta/kms/key/delete/delete.go | 10 +--------- internal/cmd/beta/kms/key/importKey/importKey.go | 10 +--------- internal/cmd/beta/kms/key/list/list.go | 10 +--------- internal/cmd/beta/kms/key/restore/restore.go | 10 +--------- internal/cmd/beta/kms/key/rotate/rotate.go | 10 +--------- internal/cmd/beta/kms/keyring/create/create.go | 10 +--------- internal/cmd/beta/kms/keyring/delete/delete.go | 10 +--------- internal/cmd/beta/kms/keyring/list/list.go | 10 +--------- internal/cmd/beta/kms/version/destroy/destroy.go | 10 +--------- internal/cmd/beta/kms/version/disable/disable.go | 10 +--------- internal/cmd/beta/kms/version/enable/enable.go | 10 +--------- internal/cmd/beta/kms/version/list/list.go | 10 +--------- internal/cmd/beta/kms/version/restore/restore.go | 10 +--------- internal/cmd/beta/kms/wrappingkey/create/create.go | 10 +--------- internal/cmd/beta/kms/wrappingkey/delete/delete.go | 10 +--------- internal/cmd/beta/kms/wrappingkey/list/list.go | 10 +--------- 17 files changed, 17 insertions(+), 153 deletions(-) diff --git a/internal/cmd/beta/kms/key/create/create.go b/internal/cmd/beta/kms/key/create/create.go index 92efb8b46..a70537b08 100644 --- a/internal/cmd/beta/kms/key/create/create.go +++ b/internal/cmd/beta/kms/key/create/create.go @@ -129,15 +129,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { Protection: flags.FlagToStringPointer(p, cmd, protectionFlag), } - if p.IsVerbosityDebug() { - modelStr, err := print.BuildDebugStrFromInputModel(model) - if err != nil { - p.Debug(print.ErrorLevel, "convert model to string for debugging: %v", err) - } else { - p.Debug(print.ErrorLevel, "parsed input values: %s", modelStr) - } - } - + p.DebugInputModel(model) return &model, nil } diff --git a/internal/cmd/beta/kms/key/delete/delete.go b/internal/cmd/beta/kms/key/delete/delete.go index bfcf35748..b3ece0758 100644 --- a/internal/cmd/beta/kms/key/delete/delete.go +++ b/internal/cmd/beta/kms/key/delete/delete.go @@ -107,15 +107,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu KeyId: keyId, } - if p.IsVerbosityDebug() { - modelStr, err := print.BuildDebugStrFromInputModel(model) - if err != nil { - p.Debug(print.ErrorLevel, "convert model to string for debugging: %v", err) - } else { - p.Debug(print.DebugLevel, "parsed input values: %s", modelStr) - } - } - + p.DebugInputModel(model) return &model, nil } diff --git a/internal/cmd/beta/kms/key/importKey/importKey.go b/internal/cmd/beta/kms/key/importKey/importKey.go index 947194c77..ede141548 100644 --- a/internal/cmd/beta/kms/key/importKey/importKey.go +++ b/internal/cmd/beta/kms/key/importKey/importKey.go @@ -121,15 +121,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu WrappingKeyId: flags.FlagToStringPointer(p, cmd, wrappingKeyIdFlag), } - if p.IsVerbosityDebug() { - modelStr, err := print.BuildDebugStrFromInputModel(model) - if err != nil { - p.Debug(print.ErrorLevel, "convert model to string for debugging: %v", err) - } else { - p.Debug(print.ErrorLevel, "parsed input values: %s", modelStr) - } - } - + p.DebugInputModel(model) return &model, nil } diff --git a/internal/cmd/beta/kms/key/list/list.go b/internal/cmd/beta/kms/key/list/list.go index a511d2d7a..b315aee4b 100644 --- a/internal/cmd/beta/kms/key/list/list.go +++ b/internal/cmd/beta/kms/key/list/list.go @@ -82,15 +82,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { KeyRingId: flags.FlagToStringValue(p, cmd, keyRingIdFlag), } - if p.IsVerbosityDebug() { - modelStr, err := print.BuildDebugStrFromInputModel(model) - if err != nil { - p.Debug(print.ErrorLevel, "convert model to string for debugging: %v", err) - } else { - p.Debug(print.DebugLevel, "parsed input values: %s", modelStr) - } - } - + p.DebugInputModel(model) return &model, nil } diff --git a/internal/cmd/beta/kms/key/restore/restore.go b/internal/cmd/beta/kms/key/restore/restore.go index 2e7e27af1..b62b8ac52 100644 --- a/internal/cmd/beta/kms/key/restore/restore.go +++ b/internal/cmd/beta/kms/key/restore/restore.go @@ -106,15 +106,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu KeyId: keyId, } - if p.IsVerbosityDebug() { - modelStr, err := print.BuildDebugStrFromInputModel(model) - if err != nil { - p.Debug(print.ErrorLevel, "convert model to string for debugging: %v", err) - } else { - p.Debug(print.DebugLevel, "parsed input values: %s", modelStr) - } - } - + p.DebugInputModel(model) return &model, nil } diff --git a/internal/cmd/beta/kms/key/rotate/rotate.go b/internal/cmd/beta/kms/key/rotate/rotate.go index 71f2e3449..f8211a38f 100644 --- a/internal/cmd/beta/kms/key/rotate/rotate.go +++ b/internal/cmd/beta/kms/key/rotate/rotate.go @@ -100,15 +100,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu KeyId: keyId, } - if p.IsVerbosityDebug() { - modelStr, err := print.BuildDebugStrFromInputModel(model) - if err != nil { - p.Debug(print.ErrorLevel, "convert model to string for debugging: %v", err) - } else { - p.Debug(print.DebugLevel, "parsed input values: %s", modelStr) - } - } - + p.DebugInputModel(model) return &model, nil } diff --git a/internal/cmd/beta/kms/keyring/create/create.go b/internal/cmd/beta/kms/keyring/create/create.go index 93fb244ba..225e69182 100644 --- a/internal/cmd/beta/kms/keyring/create/create.go +++ b/internal/cmd/beta/kms/keyring/create/create.go @@ -128,15 +128,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { Description: flags.FlagToStringValue(p, cmd, descriptionFlag), } - if p.IsVerbosityDebug() { - modelStr, err := print.BuildDebugStrFromInputModel(model) - if err != nil { - p.Debug(print.ErrorLevel, "convert model to string for debugging: %v", err) - } else { - p.Debug(print.ErrorLevel, "parsed input values: %s", modelStr) - } - } - + p.DebugInputModel(model) return &model, nil } diff --git a/internal/cmd/beta/kms/keyring/delete/delete.go b/internal/cmd/beta/kms/keyring/delete/delete.go index b22a1d372..ff2da0d39 100644 --- a/internal/cmd/beta/kms/keyring/delete/delete.go +++ b/internal/cmd/beta/kms/keyring/delete/delete.go @@ -95,15 +95,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu KeyRingId: keyRingId, } - if p.IsVerbosityDebug() { - modelStr, err := print.BuildDebugStrFromInputModel(model) - if err != nil { - p.Debug(print.ErrorLevel, "convert model to string for debugging: %v", err) - } else { - p.Debug(print.DebugLevel, "parsed input values: %s", modelStr) - } - } - + p.DebugInputModel(model) return &model, nil } diff --git a/internal/cmd/beta/kms/keyring/list/list.go b/internal/cmd/beta/kms/keyring/list/list.go index bb642fbd3..d12b9ae87 100644 --- a/internal/cmd/beta/kms/keyring/list/list.go +++ b/internal/cmd/beta/kms/keyring/list/list.go @@ -74,15 +74,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { GlobalFlagModel: globalFlags, } - if p.IsVerbosityDebug() { - modelStr, err := print.BuildDebugStrFromInputModel(model) - if err != nil { - p.Debug(print.ErrorLevel, "convert model to string for debugging: %v", err) - } else { - p.Debug(print.DebugLevel, "parsed input values: %s", modelStr) - } - } - + p.DebugInputModel(model) return &model, nil } diff --git a/internal/cmd/beta/kms/version/destroy/destroy.go b/internal/cmd/beta/kms/version/destroy/destroy.go index 0d21821b6..0e0ddc04b 100644 --- a/internal/cmd/beta/kms/version/destroy/destroy.go +++ b/internal/cmd/beta/kms/version/destroy/destroy.go @@ -103,15 +103,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu VersionNumber: versionNumber, } - if p.IsVerbosityDebug() { - modelStr, err := print.BuildDebugStrFromInputModel(model) - if err != nil { - p.Debug(print.ErrorLevel, "convert model to string for debugging: %v", err) - } else { - p.Debug(print.DebugLevel, "parsed input values: %s", modelStr) - } - } - + p.DebugInputModel(model) return &model, nil } diff --git a/internal/cmd/beta/kms/version/disable/disable.go b/internal/cmd/beta/kms/version/disable/disable.go index 8eed8e32b..92436d9b1 100644 --- a/internal/cmd/beta/kms/version/disable/disable.go +++ b/internal/cmd/beta/kms/version/disable/disable.go @@ -105,15 +105,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu VersionNumber: versionNumber, } - if p.IsVerbosityDebug() { - modelStr, err := print.BuildDebugStrFromInputModel(model) - if err != nil { - p.Debug(print.ErrorLevel, "convert model to string for debugging: %v", err) - } else { - p.Debug(print.DebugLevel, "parsed input values: %s", modelStr) - } - } - + p.DebugInputModel(model) return &model, nil } diff --git a/internal/cmd/beta/kms/version/enable/enable.go b/internal/cmd/beta/kms/version/enable/enable.go index 12c83e188..67b500798 100644 --- a/internal/cmd/beta/kms/version/enable/enable.go +++ b/internal/cmd/beta/kms/version/enable/enable.go @@ -116,15 +116,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu VersionNumber: versionNumber, } - if p.IsVerbosityDebug() { - modelStr, err := print.BuildDebugStrFromInputModel(model) - if err != nil { - p.Debug(print.ErrorLevel, "convert model to string for debugging: %v", err) - } else { - p.Debug(print.DebugLevel, "parsed input values: %s", modelStr) - } - } - + p.DebugInputModel(model) return &model, nil } diff --git a/internal/cmd/beta/kms/version/list/list.go b/internal/cmd/beta/kms/version/list/list.go index a04753f66..f595dccd7 100644 --- a/internal/cmd/beta/kms/version/list/list.go +++ b/internal/cmd/beta/kms/version/list/list.go @@ -85,15 +85,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { KeyId: flags.FlagToStringValue(p, cmd, keyIdFlag), } - if p.IsVerbosityDebug() { - modelStr, err := print.BuildDebugStrFromInputModel(model) - if err != nil { - p.Debug(print.ErrorLevel, "convert model to string for debugging: %v", err) - } else { - p.Debug(print.DebugLevel, "parsed input values: %s", modelStr) - } - } - + p.DebugInputModel(model) return &model, nil } diff --git a/internal/cmd/beta/kms/version/restore/restore.go b/internal/cmd/beta/kms/version/restore/restore.go index a0386d057..19e6e3af6 100644 --- a/internal/cmd/beta/kms/version/restore/restore.go +++ b/internal/cmd/beta/kms/version/restore/restore.go @@ -103,15 +103,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu VersionNumber: versionNumber, } - if p.IsVerbosityDebug() { - modelStr, err := print.BuildDebugStrFromInputModel(model) - if err != nil { - p.Debug(print.ErrorLevel, "convert model to string for debugging: %v", err) - } else { - p.Debug(print.DebugLevel, "parsed input values: %s", modelStr) - } - } - + p.DebugInputModel(model) return &model, nil } diff --git a/internal/cmd/beta/kms/wrappingkey/create/create.go b/internal/cmd/beta/kms/wrappingkey/create/create.go index 7d41a5514..bfb772d86 100644 --- a/internal/cmd/beta/kms/wrappingkey/create/create.go +++ b/internal/cmd/beta/kms/wrappingkey/create/create.go @@ -127,15 +127,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { Protection: flags.FlagToStringPointer(p, cmd, protectionFlag), } - if p.IsVerbosityDebug() { - modelStr, err := print.BuildDebugStrFromInputModel(model) - if err != nil { - p.Debug(print.ErrorLevel, "convert model to string for debugging: %v", err) - } else { - p.Debug(print.ErrorLevel, "parsed input values: %s", modelStr) - } - } - + p.DebugInputModel(model) return &model, nil } diff --git a/internal/cmd/beta/kms/wrappingkey/delete/delete.go b/internal/cmd/beta/kms/wrappingkey/delete/delete.go index 495e0f9d5..c4ab2dee2 100644 --- a/internal/cmd/beta/kms/wrappingkey/delete/delete.go +++ b/internal/cmd/beta/kms/wrappingkey/delete/delete.go @@ -102,15 +102,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu WrappingKeyId: wrappingKeyId, } - if p.IsVerbosityDebug() { - modelStr, err := print.BuildDebugStrFromInputModel(model) - if err != nil { - p.Debug(print.ErrorLevel, "convert model to string for debugging: %v", err) - } else { - p.Debug(print.DebugLevel, "parsed input values: %s", modelStr) - } - } - + p.DebugInputModel(model) return &model, nil } diff --git a/internal/cmd/beta/kms/wrappingkey/list/list.go b/internal/cmd/beta/kms/wrappingkey/list/list.go index 51bb07d09..0d654d58d 100644 --- a/internal/cmd/beta/kms/wrappingkey/list/list.go +++ b/internal/cmd/beta/kms/wrappingkey/list/list.go @@ -82,15 +82,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { KeyRingId: flags.FlagToStringValue(p, cmd, keyRingIdFlag), } - if p.IsVerbosityDebug() { - modelStr, err := print.BuildDebugStrFromInputModel(model) - if err != nil { - p.Debug(print.ErrorLevel, "convert model to string for debugging: %v", err) - } else { - p.Debug(print.DebugLevel, "parsed input values: %s", modelStr) - } - } - + p.DebugInputModel(model) return &model, nil } From e58bc38d19cbd3cb5f99359937d606d2f03c40ba Mon Sep 17 00:00:00 2001 From: Jan Sternagel Date: Fri, 17 Oct 2025 14:24:10 +0200 Subject: [PATCH 39/52] fix name in example form --key-ring to correct --key-ring-id --- internal/cmd/beta/kms/key/create/create.go | 4 ++-- internal/cmd/beta/kms/key/delete/delete.go | 2 +- internal/cmd/beta/kms/key/key.go | 2 +- internal/cmd/beta/kms/key/list/list.go | 4 ++-- internal/cmd/beta/kms/key/restore/restore.go | 2 +- internal/cmd/beta/kms/key/rotate/rotate.go | 2 +- internal/cmd/beta/kms/version/destroy/destroy.go | 2 +- internal/cmd/beta/kms/version/disable/disable.go | 2 +- internal/cmd/beta/kms/version/enable/enable.go | 2 +- internal/cmd/beta/kms/version/list/list.go | 4 ++-- internal/cmd/beta/kms/version/restore/restore.go | 2 +- internal/cmd/beta/kms/wrappingkey/create/create.go | 4 ++-- internal/cmd/beta/kms/wrappingkey/delete/delete.go | 2 +- internal/cmd/beta/kms/wrappingkey/list/list.go | 4 ++-- 14 files changed, 19 insertions(+), 19 deletions(-) diff --git a/internal/cmd/beta/kms/key/create/create.go b/internal/cmd/beta/kms/key/create/create.go index a70537b08..ff6901266 100644 --- a/internal/cmd/beta/kms/key/create/create.go +++ b/internal/cmd/beta/kms/key/create/create.go @@ -55,10 +55,10 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Example: examples.Build( examples.NewExample( `Create a Symmetric KMS key`, - `$ stackit beta kms key create --key-ring "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-key-name" --purpose "asymmetric_encrypt_decrypt" --protection "software"`), + `$ stackit beta kms key create --key-ring-id "XXX" --algorithm "rsa_2048_oaep_sha256" --name "my-key-name" --purpose "asymmetric_encrypt_decrypt" --protection "software"`), examples.NewExample( `Create a Message Authentication KMS key`, - `$ stackit beta kms key create --key-ring "my-keyring-id" --algorithm "hmac_sha512" --name "my-key-name" --purpose "message_authentication_code" --protection "software"`), + `$ stackit beta kms key create --key-ring-id "XXX" --algorithm "hmac_sha512" --name "my-key-name" --purpose "message_authentication_code" --protection "software"`), ), RunE: func(cmd *cobra.Command, _ []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/key/delete/delete.go b/internal/cmd/beta/kms/key/delete/delete.go index b3ece0758..66fe43543 100644 --- a/internal/cmd/beta/kms/key/delete/delete.go +++ b/internal/cmd/beta/kms/key/delete/delete.go @@ -42,7 +42,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Example: examples.Build( examples.NewExample( `Delete a KMS key "my-key-id" inside the key ring "my-key-ring-id"`, - `$ stackit beta kms key delete "my-key-id" --key-ring "my-key-ring-id"`), + `$ stackit beta kms key delete "my-key-id" --key-ring-id "my-key-ring-id"`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/key/key.go b/internal/cmd/beta/kms/key/key.go index 35cd46340..4b2f7d8fa 100644 --- a/internal/cmd/beta/kms/key/key.go +++ b/internal/cmd/beta/kms/key/key.go @@ -17,7 +17,7 @@ import ( func NewCmd(params *params.CmdParams) *cobra.Command { cmd := &cobra.Command{ Use: "key", - Short: "Manage KMS Keys", + Short: "Manage KMS keys", Long: "Provides functionality for key operations inside the KMS", Args: args.NoArgs, Run: utils.CmdHelp, diff --git a/internal/cmd/beta/kms/key/list/list.go b/internal/cmd/beta/kms/key/list/list.go index b315aee4b..2b909c5f9 100644 --- a/internal/cmd/beta/kms/key/list/list.go +++ b/internal/cmd/beta/kms/key/list/list.go @@ -38,10 +38,10 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Example: examples.Build( examples.NewExample( `List all KMS keys for the key ring "my-key-ring-id"`, - `$ stackit beta kms key list --key-ring "my-key-ring-id"`), + `$ stackit beta kms key list --key-ring-id "my-key-ring-id"`), examples.NewExample( `List all KMS keys in JSON format`, - `$ stackit beta kms key list --key-ring "my-key-ring-id" --output-format json`), + `$ stackit beta kms key list --key-ring-id "my-key-ring-id" --output-format json`), ), RunE: func(cmd *cobra.Command, _ []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/key/restore/restore.go b/internal/cmd/beta/kms/key/restore/restore.go index b62b8ac52..e9454a760 100644 --- a/internal/cmd/beta/kms/key/restore/restore.go +++ b/internal/cmd/beta/kms/key/restore/restore.go @@ -42,7 +42,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Example: examples.Build( examples.NewExample( `Restore a KMS key "my-key-id" inside the key ring "my-key-ring-id" that was scheduled for deletion.`, - `$ stackit beta kms keyring restore "my-key-id" --key-ring "my-key-ring-id"`), + `$ stackit beta kms keyring restore "my-key-id" --key-ring-id "my-key-ring-id"`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/key/rotate/rotate.go b/internal/cmd/beta/kms/key/rotate/rotate.go index f8211a38f..9339a544b 100644 --- a/internal/cmd/beta/kms/key/rotate/rotate.go +++ b/internal/cmd/beta/kms/key/rotate/rotate.go @@ -42,7 +42,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Example: examples.Build( examples.NewExample( `Rotate a KMS key "my-key-id" and increase it's version inside the key ring "my-key-ring-id".`, - `$ stackit beta kms key rotate "my-key-id" --key-ring "my-key-ring-id"`), + `$ stackit beta kms key rotate "my-key-id" --key-ring-id "my-key-ring-id"`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/version/destroy/destroy.go b/internal/cmd/beta/kms/version/destroy/destroy.go index 0e0ddc04b..80cc65399 100644 --- a/internal/cmd/beta/kms/version/destroy/destroy.go +++ b/internal/cmd/beta/kms/version/destroy/destroy.go @@ -43,7 +43,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Example: examples.Build( examples.NewExample( `Destroy key version "42" for the key "my-key-id" inside the key ring "my-key-ring-id"`, - `$ stackit beta kms version destroy 42 --key "my-key-id" --key-ring "my-key-ring-id"`), + `$ stackit beta kms version destroy 42 --key "my-key-id" --key-ring-id "my-key-ring-id"`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/version/disable/disable.go b/internal/cmd/beta/kms/version/disable/disable.go index 92436d9b1..e228d2efe 100644 --- a/internal/cmd/beta/kms/version/disable/disable.go +++ b/internal/cmd/beta/kms/version/disable/disable.go @@ -43,7 +43,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Example: examples.Build( examples.NewExample( `Disable key version "42" for the key "my-key-id" inside the key ring "my-key-ring-id"`, - `$ stackit beta kms version disable 42 --key "my-key-id" --key-ring "my-key-ring-id"`), + `$ stackit beta kms version disable 42 --key "my-key-id" --key-ring-id "my-key-ring-id"`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/version/enable/enable.go b/internal/cmd/beta/kms/version/enable/enable.go index 67b500798..240d897de 100644 --- a/internal/cmd/beta/kms/version/enable/enable.go +++ b/internal/cmd/beta/kms/version/enable/enable.go @@ -45,7 +45,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Example: examples.Build( examples.NewExample( `Enable key version "42" for the key "my-key-id" inside the key ring "my-key-ring-id"`, - `$ stackit beta kms version enable 42 --key "my-key-id" --key-ring "my-key-ring-id"`), + `$ stackit beta kms version enable 42 --key "my-key-id" --key-ring-id "my-key-ring-id"`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/version/list/list.go b/internal/cmd/beta/kms/version/list/list.go index f595dccd7..8eb494e39 100644 --- a/internal/cmd/beta/kms/version/list/list.go +++ b/internal/cmd/beta/kms/version/list/list.go @@ -40,10 +40,10 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Example: examples.Build( examples.NewExample( `List all key versions for the key "my-key-id" inside the key ring "my-key-ring-id"`, - `$ stackit beta kms version list --key "my-key-id" --key-ring "my-key-ring-id"`), + `$ stackit beta kms version list --key "my-key-id" --key-ring-id "my-key-ring-id"`), examples.NewExample( `List all key versions in JSON format`, - `$ stackit beta kms version list --key "my-key-id" --key-ring "my-key-ring-id" -o json`), + `$ stackit beta kms version list --key "my-key-id" --key-ring-id "my-key-ring-id" -o json`), ), RunE: func(cmd *cobra.Command, _ []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/version/restore/restore.go b/internal/cmd/beta/kms/version/restore/restore.go index 19e6e3af6..5954d6273 100644 --- a/internal/cmd/beta/kms/version/restore/restore.go +++ b/internal/cmd/beta/kms/version/restore/restore.go @@ -43,7 +43,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Example: examples.Build( examples.NewExample( `Restore key version "42" for the key "my-key-id" inside the key ring "my-key-ring-id"`, - `$ stackit beta kms version restore 42 --key "my-key-id" --key-ring "my-key-ring-id"`), + `$ stackit beta kms version restore 42 --key "my-key-id" --key-ring-id "my-key-ring-id"`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/wrappingkey/create/create.go b/internal/cmd/beta/kms/wrappingkey/create/create.go index bfb772d86..7b5774ce4 100644 --- a/internal/cmd/beta/kms/wrappingkey/create/create.go +++ b/internal/cmd/beta/kms/wrappingkey/create/create.go @@ -53,10 +53,10 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Example: examples.Build( examples.NewExample( `Create a Symmetric KMS wrapping key`, - `$ stackit beta kms wrapping-key create --key-ring "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-wrapping-key-name" --purpose "wrap_symmetric_key" --protection "software"`), + `$ stackit beta kms wrapping-key create --key-ring-id "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-wrapping-key-name" --purpose "wrap_symmetric_key" --protection "software"`), examples.NewExample( `Create an Asymmetric KMS wrapping key with a description`, - `$ stackit beta kms wrapping-key create --key-ring "my-keyring-id" --algorithm "hmac_sha256" --name "my-wrapping-key-name" --description "my-description" --purpose "wrap_asymmetric_key" --protection "software"`), + `$ stackit beta kms wrapping-key create --key-ring-id "my-keyring-id" --algorithm "hmac_sha256" --name "my-wrapping-key-name" --description "my-description" --purpose "wrap_asymmetric_key" --protection "software"`), ), RunE: func(cmd *cobra.Command, _ []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/wrappingkey/delete/delete.go b/internal/cmd/beta/kms/wrappingkey/delete/delete.go index c4ab2dee2..60f8ad79e 100644 --- a/internal/cmd/beta/kms/wrappingkey/delete/delete.go +++ b/internal/cmd/beta/kms/wrappingkey/delete/delete.go @@ -40,7 +40,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Example: examples.Build( examples.NewExample( `Delete a KMS wrapping key "my-wrapping-key-id" inside the key ring "my-key-ring-id"`, - `$ stackit beta kms wrapping-key delete "my-wrapping-key-id" --key-ring "my-key-ring-id"`), + `$ stackit beta kms wrapping-key delete "my-wrapping-key-id" --key-ring-id "my-key-ring-id"`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/wrappingkey/list/list.go b/internal/cmd/beta/kms/wrappingkey/list/list.go index 0d654d58d..da113896c 100644 --- a/internal/cmd/beta/kms/wrappingkey/list/list.go +++ b/internal/cmd/beta/kms/wrappingkey/list/list.go @@ -38,10 +38,10 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Example: examples.Build( examples.NewExample( `List all KMS wrapping keys for the key ring "my-key-ring-id"`, - `$ stackit beta kms wrapping-key list --key-ring "my-key-ring-id"`), + `$ stackit beta kms wrapping-key list --key-ring-id "my-key-ring-id"`), examples.NewExample( `List all KMS wrapping keys in JSON format`, - `$ stackit beta kms wrappingkeys list --key-ring "my-key-ring-id" --output-format json`), + `$ stackit beta kms wrappingkeys list --key-ring-id "my-key-ring-id" --output-format json`), ), RunE: func(cmd *cobra.Command, _ []string) error { ctx := context.Background() From 519f724c4b550fb6eb8e39f5a3af22192954c30e Mon Sep 17 00:00:00 2001 From: Jan Sternagel Date: Fri, 17 Oct 2025 15:04:39 +0200 Subject: [PATCH 40/52] Fix feedback for async operations --- internal/cmd/beta/kms/key/create/create.go | 27 +++++++------- .../cmd/beta/kms/key/create/create_test.go | 35 +++++++++---------- .../cmd/beta/kms/key/importKey/importKey.go | 2 +- internal/cmd/beta/kms/key/rotate/rotate.go | 2 +- .../cmd/beta/kms/keyring/create/create.go | 24 ++++++------- .../beta/kms/keyring/create/create_test.go | 35 +++++++++---------- .../cmd/beta/kms/keyring/delete/delete.go | 6 ++-- .../cmd/beta/kms/wrappingkey/create/create.go | 24 ++++++------- .../kms/wrappingkey/create/create_test.go | 35 +++++++++---------- .../cmd/beta/kms/wrappingkey/delete/delete.go | 2 +- 10 files changed, 89 insertions(+), 103 deletions(-) diff --git a/internal/cmd/beta/kms/key/create/create.go b/internal/cmd/beta/kms/key/create/create.go index ff6901266..050289e9a 100644 --- a/internal/cmd/beta/kms/key/create/create.go +++ b/internal/cmd/beta/kms/key/create/create.go @@ -17,7 +17,6 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/flags" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/print" - "github.com/stackitcloud/stackit-cli/internal/pkg/projectname" "github.com/stackitcloud/stackit-cli/internal/pkg/utils" "github.com/stackitcloud/stackit-sdk-go/services/kms" "github.com/stackitcloud/stackit-sdk-go/services/kms/wait" @@ -55,10 +54,10 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Example: examples.Build( examples.NewExample( `Create a Symmetric KMS key`, - `$ stackit beta kms key create --key-ring-id "XXX" --algorithm "rsa_2048_oaep_sha256" --name "my-key-name" --purpose "asymmetric_encrypt_decrypt" --protection "software"`), + `$ stackit beta kms key create --key-ring-id "my-key-ring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-key-name" --purpose "asymmetric_encrypt_decrypt" --protection "software"`), examples.NewExample( `Create a Message Authentication KMS key`, - `$ stackit beta kms key create --key-ring-id "XXX" --algorithm "hmac_sha512" --name "my-key-name" --purpose "message_authentication_code" --protection "software"`), + `$ stackit beta kms key create --key-ring-id "my-key-ring-id" --algorithm "hmac_sha512" --name "my-key-name" --purpose "message_authentication_code" --protection "software"`), ), RunE: func(cmd *cobra.Command, _ []string) error { ctx := context.Background() @@ -73,15 +72,8 @@ func NewCmd(params *params.CmdParams) *cobra.Command { return err } - projectLabel, err := projectname.GetProjectName(ctx, params.Printer, params.CliVersion, cmd) - if err != nil { - params.Printer.Debug(print.ErrorLevel, "get project name: %v", err) - projectLabel = model.ProjectId - } - if !model.AssumeYes { - prompt := fmt.Sprintf("Are you sure you want to create a KMS Key for project %q?", projectLabel) - err = params.Printer.PromptForConfirmation(prompt) + err = params.Printer.PromptForConfirmation("Are you sure you want to create a KMS Key?") if err != nil { return err } @@ -105,7 +97,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { s.Stop() } - return outputResult(params.Printer, model.OutputFormat, projectLabel, resp) + return outputResult(params.Printer, model, resp) }, } configureFlags(cmd) @@ -151,12 +143,12 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient kmsKeyClient return req, nil } -func outputResult(p *print.Printer, outputFormat, projectLabel string, resp *kms.Key) error { +func outputResult(p *print.Printer, model *inputModel, resp *kms.Key) error { if resp == nil { return fmt.Errorf("response is nil") } - switch outputFormat { + switch model.OutputFormat { case print.JSONOutputFormat: details, err := json.MarshalIndent(resp, "", " ") if err != nil { @@ -172,7 +164,12 @@ func outputResult(p *print.Printer, outputFormat, projectLabel string, resp *kms p.Outputln(string(details)) default: - p.Outputf("Created the key '%s' for project %q. Key ID: %s\n", utils.PtrString(resp.DisplayName), projectLabel, utils.PtrString(resp.Id)) + operationState := "Created" + if model.Async { + operationState = "Triggered creation of" + } + p.Outputf("%s the KMS key '%s'. Key ID: %s\n", operationState, utils.PtrString(resp.DisplayName), utils.PtrString(resp.Id)) + } return nil } diff --git a/internal/cmd/beta/kms/key/create/create_test.go b/internal/cmd/beta/kms/key/create/create_test.go index 82394b8cf..14e0a84b1 100644 --- a/internal/cmd/beta/kms/key/create/create_test.go +++ b/internal/cmd/beta/kms/key/create/create_test.go @@ -284,11 +284,10 @@ func TestBuildRequest(t *testing.T) { func TestOutputResult(t *testing.T) { tests := []struct { - description string - key *kms.Key - outputFormat string - projectLabel string - wantErr bool + description string + model *inputModel + key *kms.Key + wantErr bool }{ { description: "nil response", @@ -296,22 +295,22 @@ func TestOutputResult(t *testing.T) { wantErr: true, }, { - description: "default output", - key: &kms.Key{}, - projectLabel: "my-project", - wantErr: false, + description: "default output", + key: &kms.Key{}, + model: &inputModel{GlobalFlagModel: &globalflags.GlobalFlagModel{}}, + wantErr: false, }, { - description: "json output", - key: &kms.Key{}, - outputFormat: print.JSONOutputFormat, - wantErr: false, + description: "json output", + key: &kms.Key{}, + model: &inputModel{GlobalFlagModel: &globalflags.GlobalFlagModel{OutputFormat: print.JSONOutputFormat}}, + wantErr: false, }, { - description: "yaml output", - key: &kms.Key{}, - outputFormat: print.YAMLOutputFormat, - wantErr: false, + description: "yaml output", + key: &kms.Key{}, + model: &inputModel{GlobalFlagModel: &globalflags.GlobalFlagModel{OutputFormat: print.YAMLOutputFormat}}, + wantErr: false, }, } @@ -319,7 +318,7 @@ func TestOutputResult(t *testing.T) { p.Cmd = NewCmd(¶ms.CmdParams{Printer: p}) for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { - err := outputResult(p, tt.outputFormat, tt.projectLabel, tt.key) + err := outputResult(p, tt.model, tt.key) if (err != nil) != tt.wantErr { t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr) } diff --git a/internal/cmd/beta/kms/key/importKey/importKey.go b/internal/cmd/beta/kms/key/importKey/importKey.go index ede141548..19695c895 100644 --- a/internal/cmd/beta/kms/key/importKey/importKey.go +++ b/internal/cmd/beta/kms/key/importKey/importKey.go @@ -47,7 +47,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Example: examples.Build( examples.NewExample( `Import a new version for the given KMS key "my-key-id"`, - `$ stackit beta kms key import "my-key-id" --key-ring "my-keyring-id" --wrapped-key "base64-encoded-wrapped-key-material" --wrapping-key-id "my-wrapping-key-id"`), + `$ stackit beta kms key import "my-key-id" --key-ring-id "my-keyring-id" --wrapped-key "base64-encoded-wrapped-key-material" --wrapping-key-id "my-wrapping-key-id"`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/key/rotate/rotate.go b/internal/cmd/beta/kms/key/rotate/rotate.go index 9339a544b..292ab4706 100644 --- a/internal/cmd/beta/kms/key/rotate/rotate.go +++ b/internal/cmd/beta/kms/key/rotate/rotate.go @@ -64,7 +64,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { } if !model.AssumeYes { - prompt := fmt.Sprintf("Are you sure you want to rotate the key %q? (This cannot be undone)", keyName) + prompt := fmt.Sprintf("Are you sure you want to rotate the key %q? (this cannot be undone)", keyName) err = params.Printer.PromptForConfirmation(prompt) if err != nil { return err diff --git a/internal/cmd/beta/kms/keyring/create/create.go b/internal/cmd/beta/kms/keyring/create/create.go index 225e69182..71bab26a8 100644 --- a/internal/cmd/beta/kms/keyring/create/create.go +++ b/internal/cmd/beta/kms/keyring/create/create.go @@ -17,7 +17,6 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/flags" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/print" - "github.com/stackitcloud/stackit-cli/internal/pkg/projectname" "github.com/stackitcloud/stackit-cli/internal/pkg/utils" "github.com/stackitcloud/stackit-sdk-go/services/kms" "github.com/stackitcloud/stackit-sdk-go/services/kms/wait" @@ -61,15 +60,8 @@ func NewCmd(params *params.CmdParams) *cobra.Command { return err } - projectLabel, err := projectname.GetProjectName(ctx, params.Printer, params.CliVersion, cmd) - if err != nil { - params.Printer.Debug(print.ErrorLevel, "get project name: %v", err) - projectLabel = model.ProjectId - } - if !model.AssumeYes { - prompt := fmt.Sprintf("Are you sure you want to create a KMS key ring for project %q?", projectLabel) - err = params.Printer.PromptForConfirmation(prompt) + err = params.Printer.PromptForConfirmation("Are you sure you want to create a KMS key ring?") if err != nil { return err } @@ -93,7 +85,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { // Wait for async operation, if async mode not enabled if !model.Async { s := spinner.New(params.Printer) - s.Start("Creating instance") + s.Start("Creating key ring") _, err = wait.CreateKeyRingWaitHandler(ctx, apiClient, model.ProjectId, model.Region, keyRingId).WaitWithContext(ctx) if err != nil { return fmt.Errorf("wait for KMS key ring creation: %w", err) @@ -101,7 +93,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { s.Stop() } - return outputResult(params.Printer, model.OutputFormat, projectLabel, keyRing) + return outputResult(params.Printer, model, keyRing) }, } configureFlags(cmd) @@ -148,12 +140,12 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient kmsKeyringCl return req, nil } -func outputResult(p *print.Printer, outputFormat, projectLabel string, resp *kms.KeyRing) error { +func outputResult(p *print.Printer, model *inputModel, resp *kms.KeyRing) error { if resp == nil { return fmt.Errorf("response is nil") } - switch outputFormat { + switch model.OutputFormat { case print.JSONOutputFormat: details, err := json.MarshalIndent(resp, "", " ") if err != nil { @@ -169,7 +161,11 @@ func outputResult(p *print.Printer, outputFormat, projectLabel string, resp *kms p.Outputln(string(details)) default: - p.Outputf("Created instance for project %q. Key ring ID: %s\n", projectLabel, utils.PtrString(resp.Id)) + operationState := "Created" + if model.Async { + operationState = "Triggered creation of" + } + p.Outputf("%s key ring. KMS key ring ID: %s\n", operationState, utils.PtrString(resp.Id)) } return nil } diff --git a/internal/cmd/beta/kms/keyring/create/create_test.go b/internal/cmd/beta/kms/keyring/create/create_test.go index 02a66cda6..8cdf81219 100644 --- a/internal/cmd/beta/kms/keyring/create/create_test.go +++ b/internal/cmd/beta/kms/keyring/create/create_test.go @@ -206,11 +206,10 @@ func TestBuildRequest(t *testing.T) { func TestOutputResult(t *testing.T) { tests := []struct { - description string - keyRing *kms.KeyRing - outputFormat string - projectLabel string - wantErr bool + model *inputModel + description string + keyRing *kms.KeyRing + wantErr bool }{ { description: "nil response", @@ -218,22 +217,22 @@ func TestOutputResult(t *testing.T) { wantErr: true, }, { - description: "default output", - keyRing: &kms.KeyRing{}, - projectLabel: "my-project", - wantErr: false, + description: "default output", + model: &inputModel{GlobalFlagModel: &globalflags.GlobalFlagModel{}}, + keyRing: &kms.KeyRing{}, + wantErr: false, }, { - description: "json output", - keyRing: &kms.KeyRing{}, - outputFormat: print.JSONOutputFormat, - wantErr: false, + description: "json output", + model: &inputModel{GlobalFlagModel: &globalflags.GlobalFlagModel{OutputFormat: print.JSONOutputFormat}}, + keyRing: &kms.KeyRing{}, + wantErr: false, }, { - description: "yaml output", - keyRing: &kms.KeyRing{}, - outputFormat: print.YAMLOutputFormat, - wantErr: false, + description: "yaml output", + model: &inputModel{GlobalFlagModel: &globalflags.GlobalFlagModel{OutputFormat: print.YAMLOutputFormat}}, + keyRing: &kms.KeyRing{}, + wantErr: false, }, } @@ -241,7 +240,7 @@ func TestOutputResult(t *testing.T) { p.Cmd = NewCmd(¶ms.CmdParams{Printer: p}) for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { - err := outputResult(p, tt.outputFormat, tt.projectLabel, tt.keyRing) + err := outputResult(p, tt.model, tt.keyRing) if (err != nil) != tt.wantErr { t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr) } diff --git a/internal/cmd/beta/kms/keyring/delete/delete.go b/internal/cmd/beta/kms/keyring/delete/delete.go index ff2da0d39..2ec6d2ef3 100644 --- a/internal/cmd/beta/kms/keyring/delete/delete.go +++ b/internal/cmd/beta/kms/keyring/delete/delete.go @@ -19,7 +19,7 @@ import ( ) const ( - keyRingIdArg = "KEYRING_ID" + keyRingIdArg = "KEY_RING_ID" ) type inputModel struct { @@ -58,7 +58,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { } if !model.AssumeYes { - prompt := fmt.Sprintf("Are you sure you want to delete key ring %q? (This cannot be undone)", keyRingLabel) + prompt := fmt.Sprintf("Are you sure you want to delete key ring %q? (this cannot be undone)", keyRingLabel) err = params.Printer.PromptForConfirmation(prompt) if err != nil { return err @@ -72,7 +72,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { return fmt.Errorf("delete KMS key ring: %w", err) } - // Wait for async operation not relevant. Key ring deletion is synchronous. + // No async wait required; key ring deletion is synchronous. // Don't output anything. It's a deletion. params.Printer.Info("Deleted the key ring %q\n", keyRingLabel) diff --git a/internal/cmd/beta/kms/wrappingkey/create/create.go b/internal/cmd/beta/kms/wrappingkey/create/create.go index 7b5774ce4..ca3515c98 100644 --- a/internal/cmd/beta/kms/wrappingkey/create/create.go +++ b/internal/cmd/beta/kms/wrappingkey/create/create.go @@ -17,7 +17,6 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/flags" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/print" - "github.com/stackitcloud/stackit-cli/internal/pkg/projectname" "github.com/stackitcloud/stackit-cli/internal/pkg/utils" "github.com/stackitcloud/stackit-sdk-go/services/kms" "github.com/stackitcloud/stackit-sdk-go/services/kms/wait" @@ -71,15 +70,8 @@ func NewCmd(params *params.CmdParams) *cobra.Command { return err } - projectLabel, err := projectname.GetProjectName(ctx, params.Printer, params.CliVersion, cmd) - if err != nil { - params.Printer.Debug(print.ErrorLevel, "get project name: %v", err) - projectLabel = model.ProjectId - } - if !model.AssumeYes { - prompt := fmt.Sprintf("Are you sure you want to create a KMS wrapping key for project %q?", projectLabel) - err = params.Printer.PromptForConfirmation(prompt) + err = params.Printer.PromptForConfirmation("Are you sure you want to create a KMS wrapping key?") if err != nil { return err } @@ -95,7 +87,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { // Wait for async operation, if async mode not enabled if !model.Async { s := spinner.New(params.Printer) - s.Start("Creating instance") + s.Start("Creating wrapping key") _, err = wait.CreateWrappingKeyWaitHandler(ctx, apiClient, model.ProjectId, model.Region, *wrappingKey.KeyRingId, *wrappingKey.Id).WaitWithContext(ctx) if err != nil { return fmt.Errorf("wait for KMS wrapping key creation: %w", err) @@ -103,7 +95,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { s.Stop() } - return outputResult(params.Printer, model.OutputFormat, projectLabel, wrappingKey) + return outputResult(params.Printer, model, wrappingKey) }, } configureFlags(cmd) @@ -148,12 +140,12 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient kmsWrappingK return req, nil } -func outputResult(p *print.Printer, outputFormat, projectLabel string, resp *kms.WrappingKey) error { +func outputResult(p *print.Printer, model *inputModel, resp *kms.WrappingKey) error { if resp == nil { return fmt.Errorf("response is nil") } - switch outputFormat { + switch model.OutputFormat { case print.JSONOutputFormat: details, err := json.MarshalIndent(resp, "", " ") if err != nil { @@ -169,7 +161,11 @@ func outputResult(p *print.Printer, outputFormat, projectLabel string, resp *kms p.Outputln(string(details)) default: - p.Outputf("Created wrapping key for project %q. wrapping key ID: %s\n", projectLabel, utils.PtrString(resp.Id)) + operationState := "Created" + if model.Async { + operationState = "Triggered creation of" + } + p.Outputf("%s wrapping key. Wrapping key ID: %s\n", operationState, utils.PtrString(resp.Id)) } return nil diff --git a/internal/cmd/beta/kms/wrappingkey/create/create_test.go b/internal/cmd/beta/kms/wrappingkey/create/create_test.go index ae55d9512..f92cee851 100644 --- a/internal/cmd/beta/kms/wrappingkey/create/create_test.go +++ b/internal/cmd/beta/kms/wrappingkey/create/create_test.go @@ -275,11 +275,10 @@ func TestBuildRequest(t *testing.T) { func TestOutputResult(t *testing.T) { tests := []struct { - description string - wrappingKey *kms.WrappingKey - outputFormat string - projectLabel string - wantErr bool + description string + model *inputModel + wrappingKey *kms.WrappingKey + wantErr bool }{ { description: "nil response", @@ -287,22 +286,22 @@ func TestOutputResult(t *testing.T) { wantErr: true, }, { - description: "default output", - wrappingKey: &kms.WrappingKey{}, - projectLabel: "my-project", - wantErr: false, + description: "default output", + model: &inputModel{GlobalFlagModel: &globalflags.GlobalFlagModel{}}, + wrappingKey: &kms.WrappingKey{}, + wantErr: false, }, { - description: "json output", - wrappingKey: &kms.WrappingKey{}, - outputFormat: print.JSONOutputFormat, - wantErr: false, + description: "json output", + model: &inputModel{GlobalFlagModel: &globalflags.GlobalFlagModel{OutputFormat: print.JSONOutputFormat}}, + wrappingKey: &kms.WrappingKey{}, + wantErr: false, }, { - description: "yaml output", - wrappingKey: &kms.WrappingKey{}, - outputFormat: print.YAMLOutputFormat, - wantErr: false, + description: "yaml output", + model: &inputModel{GlobalFlagModel: &globalflags.GlobalFlagModel{OutputFormat: print.YAMLOutputFormat}}, + wrappingKey: &kms.WrappingKey{}, + wantErr: false, }, } @@ -310,7 +309,7 @@ func TestOutputResult(t *testing.T) { p.Cmd = NewCmd(¶ms.CmdParams{Printer: p}) for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { - err := outputResult(p, tt.outputFormat, tt.projectLabel, tt.wrappingKey) + err := outputResult(p, tt.model, tt.wrappingKey) if (err != nil) != tt.wantErr { t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr) } diff --git a/internal/cmd/beta/kms/wrappingkey/delete/delete.go b/internal/cmd/beta/kms/wrappingkey/delete/delete.go index 60f8ad79e..b1cca4d58 100644 --- a/internal/cmd/beta/kms/wrappingkey/delete/delete.go +++ b/internal/cmd/beta/kms/wrappingkey/delete/delete.go @@ -62,7 +62,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { } if !model.AssumeYes { - prompt := fmt.Sprintf("Are you sure you want to delete the wrapping key %q? (This cannot be undone)", wrappingKeyName) + prompt := fmt.Sprintf("Are you sure you want to delete the wrapping key %q? (this cannot be undone)", wrappingKeyName) err = params.Printer.PromptForConfirmation(prompt) if err != nil { return err From ae9a66ab7ffa260c308d275ad17f40a9db10b31e Mon Sep 17 00:00:00 2001 From: Jan Sternagel Date: Fri, 17 Oct 2025 15:12:52 +0200 Subject: [PATCH 41/52] fix name in example form --key to correct --key-id --- internal/cmd/beta/kms/version/destroy/destroy.go | 2 +- internal/cmd/beta/kms/version/disable/disable.go | 2 +- internal/cmd/beta/kms/version/enable/enable.go | 2 +- internal/cmd/beta/kms/version/list/list.go | 4 ++-- internal/cmd/beta/kms/version/restore/restore.go | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/internal/cmd/beta/kms/version/destroy/destroy.go b/internal/cmd/beta/kms/version/destroy/destroy.go index 80cc65399..f999ad7a2 100644 --- a/internal/cmd/beta/kms/version/destroy/destroy.go +++ b/internal/cmd/beta/kms/version/destroy/destroy.go @@ -43,7 +43,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Example: examples.Build( examples.NewExample( `Destroy key version "42" for the key "my-key-id" inside the key ring "my-key-ring-id"`, - `$ stackit beta kms version destroy 42 --key "my-key-id" --key-ring-id "my-key-ring-id"`), + `$ stackit beta kms version destroy 42 --key-id "my-key-id" --key-ring-id "my-key-ring-id"`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/version/disable/disable.go b/internal/cmd/beta/kms/version/disable/disable.go index e228d2efe..a68ec054b 100644 --- a/internal/cmd/beta/kms/version/disable/disable.go +++ b/internal/cmd/beta/kms/version/disable/disable.go @@ -43,7 +43,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Example: examples.Build( examples.NewExample( `Disable key version "42" for the key "my-key-id" inside the key ring "my-key-ring-id"`, - `$ stackit beta kms version disable 42 --key "my-key-id" --key-ring-id "my-key-ring-id"`), + `$ stackit beta kms version disable 42 --key-id "my-key-id" --key-ring-id "my-key-ring-id"`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/version/enable/enable.go b/internal/cmd/beta/kms/version/enable/enable.go index 240d897de..4dedf5fc1 100644 --- a/internal/cmd/beta/kms/version/enable/enable.go +++ b/internal/cmd/beta/kms/version/enable/enable.go @@ -45,7 +45,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Example: examples.Build( examples.NewExample( `Enable key version "42" for the key "my-key-id" inside the key ring "my-key-ring-id"`, - `$ stackit beta kms version enable 42 --key "my-key-id" --key-ring-id "my-key-ring-id"`), + `$ stackit beta kms version enable 42 --key-id "my-key-id" --key-ring-id "my-key-ring-id"`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/version/list/list.go b/internal/cmd/beta/kms/version/list/list.go index 8eb494e39..7c970fde4 100644 --- a/internal/cmd/beta/kms/version/list/list.go +++ b/internal/cmd/beta/kms/version/list/list.go @@ -40,10 +40,10 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Example: examples.Build( examples.NewExample( `List all key versions for the key "my-key-id" inside the key ring "my-key-ring-id"`, - `$ stackit beta kms version list --key "my-key-id" --key-ring-id "my-key-ring-id"`), + `$ stackit beta kms version list --key-id "my-key-id" --key-ring-id "my-key-ring-id"`), examples.NewExample( `List all key versions in JSON format`, - `$ stackit beta kms version list --key "my-key-id" --key-ring-id "my-key-ring-id" -o json`), + `$ stackit beta kms version list --key-id "my-key-id" --key-ring-id "my-key-ring-id" -o json`), ), RunE: func(cmd *cobra.Command, _ []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/version/restore/restore.go b/internal/cmd/beta/kms/version/restore/restore.go index 5954d6273..6acfe3960 100644 --- a/internal/cmd/beta/kms/version/restore/restore.go +++ b/internal/cmd/beta/kms/version/restore/restore.go @@ -43,7 +43,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Example: examples.Build( examples.NewExample( `Restore key version "42" for the key "my-key-id" inside the key ring "my-key-ring-id"`, - `$ stackit beta kms version restore 42 --key "my-key-id" --key-ring-id "my-key-ring-id"`), + `$ stackit beta kms version restore 42 --key-id "my-key-id" --key-ring-id "my-key-ring-id"`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() From 996d1eec89cd815e42874af23e5a1a66efa88b67 Mon Sep 17 00:00:00 2001 From: Jan Sternagel Date: Fri, 17 Oct 2025 15:30:59 +0200 Subject: [PATCH 42/52] linter, test & docs --- docs/stackit_beta_kms.md | 2 +- docs/stackit_beta_kms_key.md | 2 +- docs/stackit_beta_kms_key_create.md | 6 +++--- docs/stackit_beta_kms_key_delete.md | 4 ++-- docs/stackit_beta_kms_key_import.md | 4 ++-- docs/stackit_beta_kms_key_list.md | 6 +++--- docs/stackit_beta_kms_key_restore.md | 4 ++-- docs/stackit_beta_kms_key_rotate.md | 4 ++-- docs/stackit_beta_kms_keyring_delete.md | 2 +- docs/stackit_beta_kms_version_destroy.md | 2 +- docs/stackit_beta_kms_version_disable.md | 2 +- docs/stackit_beta_kms_version_enable.md | 2 +- docs/stackit_beta_kms_version_list.md | 4 ++-- docs/stackit_beta_kms_version_restore.md | 2 +- docs/stackit_beta_kms_wrapping-key_create.md | 4 ++-- docs/stackit_beta_kms_wrapping-key_delete.md | 2 +- docs/stackit_beta_kms_wrapping-key_list.md | 4 ++-- internal/cmd/beta/kms/key/create/create.go | 1 - 18 files changed, 28 insertions(+), 29 deletions(-) diff --git a/docs/stackit_beta_kms.md b/docs/stackit_beta_kms.md index fac6dd01d..e50cfd05a 100644 --- a/docs/stackit_beta_kms.md +++ b/docs/stackit_beta_kms.md @@ -30,7 +30,7 @@ stackit beta kms [flags] ### SEE ALSO * [stackit beta](./stackit_beta.md) - Contains beta STACKIT CLI commands -* [stackit beta kms key](./stackit_beta_kms_key.md) - Manage KMS Keys +* [stackit beta kms key](./stackit_beta_kms_key.md) - Manage KMS keys * [stackit beta kms keyring](./stackit_beta_kms_keyring.md) - Manage KMS key rings * [stackit beta kms version](./stackit_beta_kms_version.md) - Manage KMS key versions * [stackit beta kms wrapping-key](./stackit_beta_kms_wrapping-key.md) - Manage KMS wrapping keys diff --git a/docs/stackit_beta_kms_key.md b/docs/stackit_beta_kms_key.md index 69e829720..631808f53 100644 --- a/docs/stackit_beta_kms_key.md +++ b/docs/stackit_beta_kms_key.md @@ -1,6 +1,6 @@ ## stackit beta kms key -Manage KMS Keys +Manage KMS keys ### Synopsis diff --git a/docs/stackit_beta_kms_key_create.md b/docs/stackit_beta_kms_key_create.md index 60a59d8a2..ade075f04 100644 --- a/docs/stackit_beta_kms_key_create.md +++ b/docs/stackit_beta_kms_key_create.md @@ -14,10 +14,10 @@ stackit beta kms key create [flags] ``` Create a Symmetric KMS key - $ stackit beta kms key create --key-ring "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-key-name" --purpose "asymmetric_encrypt_decrypt" --protection "software" + $ stackit beta kms key create --key-ring-id "my-key-ring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-key-name" --purpose "asymmetric_encrypt_decrypt" --protection "software" Create a Message Authentication KMS key - $ stackit beta kms key create --key-ring "my-keyring-id" --algorithm "hmac_sha512" --name "my-key-name" --purpose "message_authentication_code" --protection "software" + $ stackit beta kms key create --key-ring-id "my-key-ring-id" --algorithm "hmac_sha512" --name "my-key-name" --purpose "message_authentication_code" --protection "software" ``` ### Options @@ -46,5 +46,5 @@ stackit beta kms key create [flags] ### SEE ALSO -* [stackit beta kms key](./stackit_beta_kms_key.md) - Manage KMS Keys +* [stackit beta kms key](./stackit_beta_kms_key.md) - Manage KMS keys diff --git a/docs/stackit_beta_kms_key_delete.md b/docs/stackit_beta_kms_key_delete.md index af7c6be0a..0fedcd8d9 100644 --- a/docs/stackit_beta_kms_key_delete.md +++ b/docs/stackit_beta_kms_key_delete.md @@ -14,7 +14,7 @@ stackit beta kms key delete KEY_ID [flags] ``` Delete a KMS key "my-key-id" inside the key ring "my-key-ring-id" - $ stackit beta kms key delete "my-key-id" --key-ring "my-key-ring-id" + $ stackit beta kms key delete "my-key-id" --key-ring-id "my-key-ring-id" ``` ### Options @@ -37,5 +37,5 @@ stackit beta kms key delete KEY_ID [flags] ### SEE ALSO -* [stackit beta kms key](./stackit_beta_kms_key.md) - Manage KMS Keys +* [stackit beta kms key](./stackit_beta_kms_key.md) - Manage KMS keys diff --git a/docs/stackit_beta_kms_key_import.md b/docs/stackit_beta_kms_key_import.md index a7f8b6f4d..151545dbc 100644 --- a/docs/stackit_beta_kms_key_import.md +++ b/docs/stackit_beta_kms_key_import.md @@ -14,7 +14,7 @@ stackit beta kms key import KEY_ID [flags] ``` Import a new version for the given KMS key "my-key-id" - $ stackit beta kms key import "my-key-id" --key-ring "my-keyring-id" --wrapped-key "base64-encoded-wrapped-key-material" --wrapping-key-id "my-wrapping-key-id" + $ stackit beta kms key import "my-key-id" --key-ring-id "my-keyring-id" --wrapped-key "base64-encoded-wrapped-key-material" --wrapping-key-id "my-wrapping-key-id" ``` ### Options @@ -39,5 +39,5 @@ stackit beta kms key import KEY_ID [flags] ### SEE ALSO -* [stackit beta kms key](./stackit_beta_kms_key.md) - Manage KMS Keys +* [stackit beta kms key](./stackit_beta_kms_key.md) - Manage KMS keys diff --git a/docs/stackit_beta_kms_key_list.md b/docs/stackit_beta_kms_key_list.md index 3016764b1..8413b8fd4 100644 --- a/docs/stackit_beta_kms_key_list.md +++ b/docs/stackit_beta_kms_key_list.md @@ -14,10 +14,10 @@ stackit beta kms key list [flags] ``` List all KMS keys for the key ring "my-key-ring-id" - $ stackit beta kms key list --key-ring "my-key-ring-id" + $ stackit beta kms key list --key-ring-id "my-key-ring-id" List all KMS keys in JSON format - $ stackit beta kms key list --key-ring "my-key-ring-id" --output-format json + $ stackit beta kms key list --key-ring-id "my-key-ring-id" --output-format json ``` ### Options @@ -40,5 +40,5 @@ stackit beta kms key list [flags] ### SEE ALSO -* [stackit beta kms key](./stackit_beta_kms_key.md) - Manage KMS Keys +* [stackit beta kms key](./stackit_beta_kms_key.md) - Manage KMS keys diff --git a/docs/stackit_beta_kms_key_restore.md b/docs/stackit_beta_kms_key_restore.md index 38d22fd22..5022ec143 100644 --- a/docs/stackit_beta_kms_key_restore.md +++ b/docs/stackit_beta_kms_key_restore.md @@ -14,7 +14,7 @@ stackit beta kms key restore KEY_ID [flags] ``` Restore a KMS key "my-key-id" inside the key ring "my-key-ring-id" that was scheduled for deletion. - $ stackit beta kms keyring restore "my-key-id" --key-ring "my-key-ring-id" + $ stackit beta kms keyring restore "my-key-id" --key-ring-id "my-key-ring-id" ``` ### Options @@ -37,5 +37,5 @@ stackit beta kms key restore KEY_ID [flags] ### SEE ALSO -* [stackit beta kms key](./stackit_beta_kms_key.md) - Manage KMS Keys +* [stackit beta kms key](./stackit_beta_kms_key.md) - Manage KMS keys diff --git a/docs/stackit_beta_kms_key_rotate.md b/docs/stackit_beta_kms_key_rotate.md index 18b0ac144..54164ed00 100644 --- a/docs/stackit_beta_kms_key_rotate.md +++ b/docs/stackit_beta_kms_key_rotate.md @@ -14,7 +14,7 @@ stackit beta kms key rotate KEY_ID [flags] ``` Rotate a KMS key "my-key-id" and increase it's version inside the key ring "my-key-ring-id". - $ stackit beta kms key rotate "my-key-id" --key-ring "my-key-ring-id" + $ stackit beta kms key rotate "my-key-id" --key-ring-id "my-key-ring-id" ``` ### Options @@ -37,5 +37,5 @@ stackit beta kms key rotate KEY_ID [flags] ### SEE ALSO -* [stackit beta kms key](./stackit_beta_kms_key.md) - Manage KMS Keys +* [stackit beta kms key](./stackit_beta_kms_key.md) - Manage KMS keys diff --git a/docs/stackit_beta_kms_keyring_delete.md b/docs/stackit_beta_kms_keyring_delete.md index 668cf8341..6526bb7cf 100644 --- a/docs/stackit_beta_kms_keyring_delete.md +++ b/docs/stackit_beta_kms_keyring_delete.md @@ -7,7 +7,7 @@ Deletes a KMS key ring Deletes a KMS key ring. ``` -stackit beta kms keyring delete KEYRING_ID [flags] +stackit beta kms keyring delete KEY_RING_ID [flags] ``` ### Examples diff --git a/docs/stackit_beta_kms_version_destroy.md b/docs/stackit_beta_kms_version_destroy.md index 31ec8e56b..91911a5d2 100644 --- a/docs/stackit_beta_kms_version_destroy.md +++ b/docs/stackit_beta_kms_version_destroy.md @@ -14,7 +14,7 @@ stackit beta kms version destroy VERSION_NUMBER [flags] ``` Destroy key version "42" for the key "my-key-id" inside the key ring "my-key-ring-id" - $ stackit beta kms version destroy 42 --key "my-key-id" --key-ring "my-key-ring-id" + $ stackit beta kms version destroy 42 --key-id "my-key-id" --key-ring-id "my-key-ring-id" ``` ### Options diff --git a/docs/stackit_beta_kms_version_disable.md b/docs/stackit_beta_kms_version_disable.md index 51a07c1af..ca24c5c56 100644 --- a/docs/stackit_beta_kms_version_disable.md +++ b/docs/stackit_beta_kms_version_disable.md @@ -14,7 +14,7 @@ stackit beta kms version disable VERSION_NUMBER [flags] ``` Disable key version "42" for the key "my-key-id" inside the key ring "my-key-ring-id" - $ stackit beta kms version disable 42 --key "my-key-id" --key-ring "my-key-ring-id" + $ stackit beta kms version disable 42 --key-id "my-key-id" --key-ring-id "my-key-ring-id" ``` ### Options diff --git a/docs/stackit_beta_kms_version_enable.md b/docs/stackit_beta_kms_version_enable.md index 535f61e8b..ede4950fc 100644 --- a/docs/stackit_beta_kms_version_enable.md +++ b/docs/stackit_beta_kms_version_enable.md @@ -14,7 +14,7 @@ stackit beta kms version enable VERSION_NUMBER [flags] ``` Enable key version "42" for the key "my-key-id" inside the key ring "my-key-ring-id" - $ stackit beta kms version enable 42 --key "my-key-id" --key-ring "my-key-ring-id" + $ stackit beta kms version enable 42 --key-id "my-key-id" --key-ring-id "my-key-ring-id" ``` ### Options diff --git a/docs/stackit_beta_kms_version_list.md b/docs/stackit_beta_kms_version_list.md index 2e4311bc7..3954ce9ae 100644 --- a/docs/stackit_beta_kms_version_list.md +++ b/docs/stackit_beta_kms_version_list.md @@ -14,10 +14,10 @@ stackit beta kms version list [flags] ``` List all key versions for the key "my-key-id" inside the key ring "my-key-ring-id" - $ stackit beta kms version list --key "my-key-id" --key-ring "my-key-ring-id" + $ stackit beta kms version list --key-id "my-key-id" --key-ring-id "my-key-ring-id" List all key versions in JSON format - $ stackit beta kms version list --key "my-key-id" --key-ring "my-key-ring-id" -o json + $ stackit beta kms version list --key-id "my-key-id" --key-ring-id "my-key-ring-id" -o json ``` ### Options diff --git a/docs/stackit_beta_kms_version_restore.md b/docs/stackit_beta_kms_version_restore.md index 3dc8ad525..bd4596721 100644 --- a/docs/stackit_beta_kms_version_restore.md +++ b/docs/stackit_beta_kms_version_restore.md @@ -14,7 +14,7 @@ stackit beta kms version restore VERSION_NUMBER [flags] ``` Restore key version "42" for the key "my-key-id" inside the key ring "my-key-ring-id" - $ stackit beta kms version restore 42 --key "my-key-id" --key-ring "my-key-ring-id" + $ stackit beta kms version restore 42 --key-id "my-key-id" --key-ring-id "my-key-ring-id" ``` ### Options diff --git a/docs/stackit_beta_kms_wrapping-key_create.md b/docs/stackit_beta_kms_wrapping-key_create.md index e4165c689..6a723c7e5 100644 --- a/docs/stackit_beta_kms_wrapping-key_create.md +++ b/docs/stackit_beta_kms_wrapping-key_create.md @@ -14,10 +14,10 @@ stackit beta kms wrapping-key create [flags] ``` Create a Symmetric KMS wrapping key - $ stackit beta kms wrapping-key create --key-ring "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-wrapping-key-name" --purpose "wrap_symmetric_key" --protection "software" + $ stackit beta kms wrapping-key create --key-ring-id "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-wrapping-key-name" --purpose "wrap_symmetric_key" --protection "software" Create an Asymmetric KMS wrapping key with a description - $ stackit beta kms wrapping-key create --key-ring "my-keyring-id" --algorithm "hmac_sha256" --name "my-wrapping-key-name" --description "my-description" --purpose "wrap_asymmetric_key" --protection "software" + $ stackit beta kms wrapping-key create --key-ring-id "my-keyring-id" --algorithm "hmac_sha256" --name "my-wrapping-key-name" --description "my-description" --purpose "wrap_asymmetric_key" --protection "software" ``` ### Options diff --git a/docs/stackit_beta_kms_wrapping-key_delete.md b/docs/stackit_beta_kms_wrapping-key_delete.md index 6109cc909..f3c5f27bd 100644 --- a/docs/stackit_beta_kms_wrapping-key_delete.md +++ b/docs/stackit_beta_kms_wrapping-key_delete.md @@ -14,7 +14,7 @@ stackit beta kms wrapping-key delete WRAPPING_KEY_ID [flags] ``` Delete a KMS wrapping key "my-wrapping-key-id" inside the key ring "my-key-ring-id" - $ stackit beta kms wrapping-key delete "my-wrapping-key-id" --key-ring "my-key-ring-id" + $ stackit beta kms wrapping-key delete "my-wrapping-key-id" --key-ring-id "my-key-ring-id" ``` ### Options diff --git a/docs/stackit_beta_kms_wrapping-key_list.md b/docs/stackit_beta_kms_wrapping-key_list.md index 6848d8111..02a8e9478 100644 --- a/docs/stackit_beta_kms_wrapping-key_list.md +++ b/docs/stackit_beta_kms_wrapping-key_list.md @@ -14,10 +14,10 @@ stackit beta kms wrapping-key list [flags] ``` List all KMS wrapping keys for the key ring "my-key-ring-id" - $ stackit beta kms wrapping-key list --key-ring "my-key-ring-id" + $ stackit beta kms wrapping-key list --key-ring-id "my-key-ring-id" List all KMS wrapping keys in JSON format - $ stackit beta kms wrappingkeys list --key-ring "my-key-ring-id" --output-format json + $ stackit beta kms wrappingkeys list --key-ring-id "my-key-ring-id" --output-format json ``` ### Options diff --git a/internal/cmd/beta/kms/key/create/create.go b/internal/cmd/beta/kms/key/create/create.go index 050289e9a..6ccc337f2 100644 --- a/internal/cmd/beta/kms/key/create/create.go +++ b/internal/cmd/beta/kms/key/create/create.go @@ -169,7 +169,6 @@ func outputResult(p *print.Printer, model *inputModel, resp *kms.Key) error { operationState = "Triggered creation of" } p.Outputf("%s the KMS key '%s'. Key ID: %s\n", operationState, utils.PtrString(resp.DisplayName), utils.PtrString(resp.Id)) - } return nil } From 9824515d6c7df5f47b70510f5450dc512269e300 Mon Sep 17 00:00:00 2001 From: Jan Sternagel Date: Mon, 20 Oct 2025 10:14:06 +0200 Subject: [PATCH 43/52] `--key-ring-id` changed to `--keyring-id` --- docs/stackit_beta_kms_key_create.md | 6 +++--- docs/stackit_beta_kms_key_delete.md | 8 ++++---- docs/stackit_beta_kms_key_import.md | 4 ++-- docs/stackit_beta_kms_key_list.md | 10 +++++----- docs/stackit_beta_kms_key_restore.md | 8 ++++---- docs/stackit_beta_kms_key_rotate.md | 8 ++++---- docs/stackit_beta_kms_keyring_delete.md | 6 +++--- docs/stackit_beta_kms_version_destroy.md | 10 +++++----- docs/stackit_beta_kms_version_disable.md | 10 +++++----- docs/stackit_beta_kms_version_enable.md | 10 +++++----- docs/stackit_beta_kms_version_list.md | 12 ++++++------ docs/stackit_beta_kms_version_restore.md | 10 +++++----- docs/stackit_beta_kms_wrapping-key_create.md | 6 +++--- docs/stackit_beta_kms_wrapping-key_delete.md | 8 ++++---- docs/stackit_beta_kms_wrapping-key_list.md | 10 +++++----- internal/cmd/beta/kms/key/create/create.go | 6 +++--- internal/cmd/beta/kms/key/delete/delete.go | 6 +++--- internal/cmd/beta/kms/key/importKey/importKey.go | 4 ++-- internal/cmd/beta/kms/key/list/list.go | 8 ++++---- internal/cmd/beta/kms/key/restore/restore.go | 6 +++--- internal/cmd/beta/kms/key/rotate/rotate.go | 6 +++--- internal/cmd/beta/kms/keyring/delete/delete.go | 6 +++--- internal/cmd/beta/kms/version/destroy/destroy.go | 6 +++--- internal/cmd/beta/kms/version/disable/disable.go | 6 +++--- internal/cmd/beta/kms/version/enable/enable.go | 6 +++--- internal/cmd/beta/kms/version/list/list.go | 8 ++++---- internal/cmd/beta/kms/version/restore/restore.go | 6 +++--- internal/cmd/beta/kms/wrappingkey/create/create.go | 6 +++--- internal/cmd/beta/kms/wrappingkey/delete/delete.go | 6 +++--- internal/cmd/beta/kms/wrappingkey/list/list.go | 8 ++++---- 30 files changed, 110 insertions(+), 110 deletions(-) diff --git a/docs/stackit_beta_kms_key_create.md b/docs/stackit_beta_kms_key_create.md index ade075f04..ba19a6145 100644 --- a/docs/stackit_beta_kms_key_create.md +++ b/docs/stackit_beta_kms_key_create.md @@ -14,10 +14,10 @@ stackit beta kms key create [flags] ``` Create a Symmetric KMS key - $ stackit beta kms key create --key-ring-id "my-key-ring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-key-name" --purpose "asymmetric_encrypt_decrypt" --protection "software" + $ stackit beta kms key create --keyring-id "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-key-name" --purpose "asymmetric_encrypt_decrypt" --protection "software" Create a Message Authentication KMS key - $ stackit beta kms key create --key-ring-id "my-key-ring-id" --algorithm "hmac_sha512" --name "my-key-name" --purpose "message_authentication_code" --protection "software" + $ stackit beta kms key create --keyring-id "my-keyring-id" --algorithm "hmac_sha512" --name "my-key-name" --purpose "message_authentication_code" --protection "software" ``` ### Options @@ -27,7 +27,7 @@ stackit beta kms key create [flags] --description string Optional description of the key -h, --help Help for "stackit beta kms key create" --import-only States whether versions can be created or only imported - --key-ring-id string ID of the KMS key ring + --keyring-id string ID of the KMS key ring --name string The display name to distinguish multiple keys --protection string The underlying system that is responsible for protecting the key material. Value: 'software' --purpose string Purpose of the key. Enum: 'symmetric_encrypt_decrypt', 'asymmetric_encrypt_decrypt', 'message_authentication_code', 'asymmetric_sign_verify' diff --git a/docs/stackit_beta_kms_key_delete.md b/docs/stackit_beta_kms_key_delete.md index 0fedcd8d9..90e55d491 100644 --- a/docs/stackit_beta_kms_key_delete.md +++ b/docs/stackit_beta_kms_key_delete.md @@ -13,15 +13,15 @@ stackit beta kms key delete KEY_ID [flags] ### Examples ``` - Delete a KMS key "my-key-id" inside the key ring "my-key-ring-id" - $ stackit beta kms key delete "my-key-id" --key-ring-id "my-key-ring-id" + Delete a KMS key "my-key-id" inside the key ring "my-keyring-id" + $ stackit beta kms key delete "my-key-id" --keyring-id "my-keyring-id" ``` ### Options ``` - -h, --help Help for "stackit beta kms key delete" - --key-ring-id string ID of the KMS Key Ring where the Key is stored + -h, --help Help for "stackit beta kms key delete" + --keyring-id string ID of the KMS Key Ring where the Key is stored ``` ### Options inherited from parent commands diff --git a/docs/stackit_beta_kms_key_import.md b/docs/stackit_beta_kms_key_import.md index 151545dbc..4cc9c5c3b 100644 --- a/docs/stackit_beta_kms_key_import.md +++ b/docs/stackit_beta_kms_key_import.md @@ -14,14 +14,14 @@ stackit beta kms key import KEY_ID [flags] ``` Import a new version for the given KMS key "my-key-id" - $ stackit beta kms key import "my-key-id" --key-ring-id "my-keyring-id" --wrapped-key "base64-encoded-wrapped-key-material" --wrapping-key-id "my-wrapping-key-id" + $ stackit beta kms key import "my-key-id" --keyring-id "my-keyring-id" --wrapped-key "base64-encoded-wrapped-key-material" --wrapping-key-id "my-wrapping-key-id" ``` ### Options ``` -h, --help Help for "stackit beta kms key import" - --key-ring-id string ID of the KMS key ring + --keyring-id string ID of the KMS key ring --wrapped-key string The wrapped key material that has to be imported. Encoded in base64 --wrapping-key-id string The unique id of the wrapping key the key material has been wrapped with ``` diff --git a/docs/stackit_beta_kms_key_list.md b/docs/stackit_beta_kms_key_list.md index 8413b8fd4..533b15248 100644 --- a/docs/stackit_beta_kms_key_list.md +++ b/docs/stackit_beta_kms_key_list.md @@ -13,18 +13,18 @@ stackit beta kms key list [flags] ### Examples ``` - List all KMS keys for the key ring "my-key-ring-id" - $ stackit beta kms key list --key-ring-id "my-key-ring-id" + List all KMS keys for the key ring "my-keyring-id" + $ stackit beta kms key list --keyring-id "my-keyring-id" List all KMS keys in JSON format - $ stackit beta kms key list --key-ring-id "my-key-ring-id" --output-format json + $ stackit beta kms key list --keyring-id "my-keyring-id" --output-format json ``` ### Options ``` - -h, --help Help for "stackit beta kms key list" - --key-ring-id string ID of the KMS Key Ring where the Key is stored + -h, --help Help for "stackit beta kms key list" + --keyring-id string ID of the KMS Key Ring where the Key is stored ``` ### Options inherited from parent commands diff --git a/docs/stackit_beta_kms_key_restore.md b/docs/stackit_beta_kms_key_restore.md index 5022ec143..d0f79c400 100644 --- a/docs/stackit_beta_kms_key_restore.md +++ b/docs/stackit_beta_kms_key_restore.md @@ -13,15 +13,15 @@ stackit beta kms key restore KEY_ID [flags] ### Examples ``` - Restore a KMS key "my-key-id" inside the key ring "my-key-ring-id" that was scheduled for deletion. - $ stackit beta kms keyring restore "my-key-id" --key-ring-id "my-key-ring-id" + Restore a KMS key "my-key-id" inside the key ring "my-keyring-id" that was scheduled for deletion. + $ stackit beta kms keyring restore "my-key-id" --keyring-id "my-keyring-id" ``` ### Options ``` - -h, --help Help for "stackit beta kms key restore" - --key-ring-id string ID of the KMS Key Ring where the Key is stored + -h, --help Help for "stackit beta kms key restore" + --keyring-id string ID of the KMS Key Ring where the Key is stored ``` ### Options inherited from parent commands diff --git a/docs/stackit_beta_kms_key_rotate.md b/docs/stackit_beta_kms_key_rotate.md index 54164ed00..1f04c789e 100644 --- a/docs/stackit_beta_kms_key_rotate.md +++ b/docs/stackit_beta_kms_key_rotate.md @@ -13,15 +13,15 @@ stackit beta kms key rotate KEY_ID [flags] ### Examples ``` - Rotate a KMS key "my-key-id" and increase it's version inside the key ring "my-key-ring-id". - $ stackit beta kms key rotate "my-key-id" --key-ring-id "my-key-ring-id" + Rotate a KMS key "my-key-id" and increase it's version inside the key ring "my-keyring-id". + $ stackit beta kms key rotate "my-key-id" --keyring-id "my-keyring-id" ``` ### Options ``` - -h, --help Help for "stackit beta kms key rotate" - --key-ring-id string ID of the KMS key Ring where the key is stored + -h, --help Help for "stackit beta kms key rotate" + --keyring-id string ID of the KMS key Ring where the key is stored ``` ### Options inherited from parent commands diff --git a/docs/stackit_beta_kms_keyring_delete.md b/docs/stackit_beta_kms_keyring_delete.md index 6526bb7cf..57c190d3f 100644 --- a/docs/stackit_beta_kms_keyring_delete.md +++ b/docs/stackit_beta_kms_keyring_delete.md @@ -7,14 +7,14 @@ Deletes a KMS key ring Deletes a KMS key ring. ``` -stackit beta kms keyring delete KEY_RING_ID [flags] +stackit beta kms keyring delete KEYRING-ID [flags] ``` ### Examples ``` - Delete a KMS key ring with ID "my-key-ring-id" - $ stackit beta kms keyring delete "my-key-ring-id" + Delete a KMS key ring with ID "my-keyring-id" + $ stackit beta kms keyring delete "my-keyring-id" ``` ### Options diff --git a/docs/stackit_beta_kms_version_destroy.md b/docs/stackit_beta_kms_version_destroy.md index 91911a5d2..8a189ecf2 100644 --- a/docs/stackit_beta_kms_version_destroy.md +++ b/docs/stackit_beta_kms_version_destroy.md @@ -13,16 +13,16 @@ stackit beta kms version destroy VERSION_NUMBER [flags] ### Examples ``` - Destroy key version "42" for the key "my-key-id" inside the key ring "my-key-ring-id" - $ stackit beta kms version destroy 42 --key-id "my-key-id" --key-ring-id "my-key-ring-id" + Destroy key version "42" for the key "my-key-id" inside the key ring "my-keyring-id" + $ stackit beta kms version destroy 42 --key-id "my-key-id" --keyring-id "my-keyring-id" ``` ### Options ``` - -h, --help Help for "stackit beta kms version destroy" - --key-id string ID of the key - --key-ring-id string ID of the KMS key ring + -h, --help Help for "stackit beta kms version destroy" + --key-id string ID of the key + --keyring-id string ID of the KMS key ring ``` ### Options inherited from parent commands diff --git a/docs/stackit_beta_kms_version_disable.md b/docs/stackit_beta_kms_version_disable.md index ca24c5c56..ca560e198 100644 --- a/docs/stackit_beta_kms_version_disable.md +++ b/docs/stackit_beta_kms_version_disable.md @@ -13,16 +13,16 @@ stackit beta kms version disable VERSION_NUMBER [flags] ### Examples ``` - Disable key version "42" for the key "my-key-id" inside the key ring "my-key-ring-id" - $ stackit beta kms version disable 42 --key-id "my-key-id" --key-ring-id "my-key-ring-id" + Disable key version "42" for the key "my-key-id" inside the key ring "my-keyring-id" + $ stackit beta kms version disable 42 --key-id "my-key-id" --keyring-id "my-keyring-id" ``` ### Options ``` - -h, --help Help for "stackit beta kms version disable" - --key-id string ID of the rey - --key-ring-id string ID of the KMS key ring + -h, --help Help for "stackit beta kms version disable" + --key-id string ID of the rey + --keyring-id string ID of the KMS key ring ``` ### Options inherited from parent commands diff --git a/docs/stackit_beta_kms_version_enable.md b/docs/stackit_beta_kms_version_enable.md index ede4950fc..46d23bec0 100644 --- a/docs/stackit_beta_kms_version_enable.md +++ b/docs/stackit_beta_kms_version_enable.md @@ -13,16 +13,16 @@ stackit beta kms version enable VERSION_NUMBER [flags] ### Examples ``` - Enable key version "42" for the key "my-key-id" inside the key ring "my-key-ring-id" - $ stackit beta kms version enable 42 --key-id "my-key-id" --key-ring-id "my-key-ring-id" + Enable key version "42" for the key "my-key-id" inside the key ring "my-keyring-id" + $ stackit beta kms version enable 42 --key-id "my-key-id" --keyring-id "my-keyring-id" ``` ### Options ``` - -h, --help Help for "stackit beta kms version enable" - --key-id string ID of the key - --key-ring-id string ID of the KMS key ring + -h, --help Help for "stackit beta kms version enable" + --key-id string ID of the key + --keyring-id string ID of the KMS key ring ``` ### Options inherited from parent commands diff --git a/docs/stackit_beta_kms_version_list.md b/docs/stackit_beta_kms_version_list.md index 3954ce9ae..bd4a96747 100644 --- a/docs/stackit_beta_kms_version_list.md +++ b/docs/stackit_beta_kms_version_list.md @@ -13,19 +13,19 @@ stackit beta kms version list [flags] ### Examples ``` - List all key versions for the key "my-key-id" inside the key ring "my-key-ring-id" - $ stackit beta kms version list --key-id "my-key-id" --key-ring-id "my-key-ring-id" + List all key versions for the key "my-key-id" inside the key ring "my-keyring-id" + $ stackit beta kms version list --key-id "my-key-id" --keyring-id "my-keyring-id" List all key versions in JSON format - $ stackit beta kms version list --key-id "my-key-id" --key-ring-id "my-key-ring-id" -o json + $ stackit beta kms version list --key-id "my-key-id" --keyring-id "my-keyring-id" -o json ``` ### Options ``` - -h, --help Help for "stackit beta kms version list" - --key-id string ID of the key - --key-ring-id string ID of the KMS key ring + -h, --help Help for "stackit beta kms version list" + --key-id string ID of the key + --keyring-id string ID of the KMS key ring ``` ### Options inherited from parent commands diff --git a/docs/stackit_beta_kms_version_restore.md b/docs/stackit_beta_kms_version_restore.md index bd4596721..8b2bc84cc 100644 --- a/docs/stackit_beta_kms_version_restore.md +++ b/docs/stackit_beta_kms_version_restore.md @@ -13,16 +13,16 @@ stackit beta kms version restore VERSION_NUMBER [flags] ### Examples ``` - Restore key version "42" for the key "my-key-id" inside the key ring "my-key-ring-id" - $ stackit beta kms version restore 42 --key-id "my-key-id" --key-ring-id "my-key-ring-id" + Restore key version "42" for the key "my-key-id" inside the key ring "my-keyring-id" + $ stackit beta kms version restore 42 --key-id "my-key-id" --keyring-id "my-keyring-id" ``` ### Options ``` - -h, --help Help for "stackit beta kms version restore" - --key-id string ID of the key - --key-ring-id string ID of the KMS key ring + -h, --help Help for "stackit beta kms version restore" + --key-id string ID of the key + --keyring-id string ID of the KMS key ring ``` ### Options inherited from parent commands diff --git a/docs/stackit_beta_kms_wrapping-key_create.md b/docs/stackit_beta_kms_wrapping-key_create.md index 6a723c7e5..971eb6025 100644 --- a/docs/stackit_beta_kms_wrapping-key_create.md +++ b/docs/stackit_beta_kms_wrapping-key_create.md @@ -14,10 +14,10 @@ stackit beta kms wrapping-key create [flags] ``` Create a Symmetric KMS wrapping key - $ stackit beta kms wrapping-key create --key-ring-id "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-wrapping-key-name" --purpose "wrap_symmetric_key" --protection "software" + $ stackit beta kms wrapping-key create --keyring-id "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-wrapping-key-name" --purpose "wrap_symmetric_key" --protection "software" Create an Asymmetric KMS wrapping key with a description - $ stackit beta kms wrapping-key create --key-ring-id "my-keyring-id" --algorithm "hmac_sha256" --name "my-wrapping-key-name" --description "my-description" --purpose "wrap_asymmetric_key" --protection "software" + $ stackit beta kms wrapping-key create --keyring-id "my-keyring-id" --algorithm "hmac_sha256" --name "my-wrapping-key-name" --description "my-description" --purpose "wrap_asymmetric_key" --protection "software" ``` ### Options @@ -26,7 +26,7 @@ stackit beta kms wrapping-key create [flags] --algorithm string En-/Decryption algorithm --description string Optional description of the wrapping key -h, --help Help for "stackit beta kms wrapping-key create" - --key-ring-id string ID of the KMS key ring + --keyring-id string ID of the KMS key ring --name string The display name to distinguish multiple wrapping keys --protection string Protection of the wrapping key. Value: 'software' --purpose string Purpose of the wrapping key. Enum: 'wrap_symmetric_key', 'wrap_asymmetric_key' diff --git a/docs/stackit_beta_kms_wrapping-key_delete.md b/docs/stackit_beta_kms_wrapping-key_delete.md index f3c5f27bd..8e5204783 100644 --- a/docs/stackit_beta_kms_wrapping-key_delete.md +++ b/docs/stackit_beta_kms_wrapping-key_delete.md @@ -13,15 +13,15 @@ stackit beta kms wrapping-key delete WRAPPING_KEY_ID [flags] ### Examples ``` - Delete a KMS wrapping key "my-wrapping-key-id" inside the key ring "my-key-ring-id" - $ stackit beta kms wrapping-key delete "my-wrapping-key-id" --key-ring-id "my-key-ring-id" + Delete a KMS wrapping key "my-wrapping-key-id" inside the key ring "my-keyring-id" + $ stackit beta kms wrapping-key delete "my-wrapping-key-id" --keyring-id "my-keyring-id" ``` ### Options ``` - -h, --help Help for "stackit beta kms wrapping-key delete" - --key-ring-id string ID of the KMS key ring where the wrapping key is stored + -h, --help Help for "stackit beta kms wrapping-key delete" + --keyring-id string ID of the KMS key ring where the wrapping key is stored ``` ### Options inherited from parent commands diff --git a/docs/stackit_beta_kms_wrapping-key_list.md b/docs/stackit_beta_kms_wrapping-key_list.md index 02a8e9478..a26f303c2 100644 --- a/docs/stackit_beta_kms_wrapping-key_list.md +++ b/docs/stackit_beta_kms_wrapping-key_list.md @@ -13,18 +13,18 @@ stackit beta kms wrapping-key list [flags] ### Examples ``` - List all KMS wrapping keys for the key ring "my-key-ring-id" - $ stackit beta kms wrapping-key list --key-ring-id "my-key-ring-id" + List all KMS wrapping keys for the key ring "my-keyring-id" + $ stackit beta kms wrapping-key list --keyring-id "my-keyring-id" List all KMS wrapping keys in JSON format - $ stackit beta kms wrappingkeys list --key-ring-id "my-key-ring-id" --output-format json + $ stackit beta kms wrappingkeys list --keyring-id "my-keyring-id" --output-format json ``` ### Options ``` - -h, --help Help for "stackit beta kms wrapping-key list" - --key-ring-id string ID of the KMS Key Ring where the Key is stored + -h, --help Help for "stackit beta kms wrapping-key list" + --keyring-id string ID of the KMS Key Ring where the Key is stored ``` ### Options inherited from parent commands diff --git a/internal/cmd/beta/kms/key/create/create.go b/internal/cmd/beta/kms/key/create/create.go index 6ccc337f2..028192899 100644 --- a/internal/cmd/beta/kms/key/create/create.go +++ b/internal/cmd/beta/kms/key/create/create.go @@ -23,7 +23,7 @@ import ( ) const ( - keyRingIdFlag = "key-ring-id" + keyRingIdFlag = "keyring-id" algorithmFlag = "algorithm" descriptionFlag = "description" @@ -54,10 +54,10 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Example: examples.Build( examples.NewExample( `Create a Symmetric KMS key`, - `$ stackit beta kms key create --key-ring-id "my-key-ring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-key-name" --purpose "asymmetric_encrypt_decrypt" --protection "software"`), + `$ stackit beta kms key create --keyring-id "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-key-name" --purpose "asymmetric_encrypt_decrypt" --protection "software"`), examples.NewExample( `Create a Message Authentication KMS key`, - `$ stackit beta kms key create --key-ring-id "my-key-ring-id" --algorithm "hmac_sha512" --name "my-key-name" --purpose "message_authentication_code" --protection "software"`), + `$ stackit beta kms key create --keyring-id "my-keyring-id" --algorithm "hmac_sha512" --name "my-key-name" --purpose "message_authentication_code" --protection "software"`), ), RunE: func(cmd *cobra.Command, _ []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/key/delete/delete.go b/internal/cmd/beta/kms/key/delete/delete.go index 66fe43543..39ef637f1 100644 --- a/internal/cmd/beta/kms/key/delete/delete.go +++ b/internal/cmd/beta/kms/key/delete/delete.go @@ -24,7 +24,7 @@ import ( const ( keyIdArg = "KEY_ID" - keyRingIdFlag = "key-ring-id" + keyRingIdFlag = "keyring-id" ) type inputModel struct { @@ -41,8 +41,8 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Args: args.SingleArg(keyIdArg, utils.ValidateUUID), Example: examples.Build( examples.NewExample( - `Delete a KMS key "my-key-id" inside the key ring "my-key-ring-id"`, - `$ stackit beta kms key delete "my-key-id" --key-ring-id "my-key-ring-id"`), + `Delete a KMS key "my-key-id" inside the key ring "my-keyring-id"`, + `$ stackit beta kms key delete "my-key-id" --keyring-id "my-keyring-id"`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/key/importKey/importKey.go b/internal/cmd/beta/kms/key/importKey/importKey.go index 19695c895..096013b7a 100644 --- a/internal/cmd/beta/kms/key/importKey/importKey.go +++ b/internal/cmd/beta/kms/key/importKey/importKey.go @@ -25,7 +25,7 @@ import ( const ( keyIdArg = "KEY_ID" - keyRingIdFlag = "key-ring-id" + keyRingIdFlag = "keyring-id" wrappedKeyFlag = "wrapped-key" wrappingKeyIdFlag = "wrapping-key-id" ) @@ -47,7 +47,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Example: examples.Build( examples.NewExample( `Import a new version for the given KMS key "my-key-id"`, - `$ stackit beta kms key import "my-key-id" --key-ring-id "my-keyring-id" --wrapped-key "base64-encoded-wrapped-key-material" --wrapping-key-id "my-wrapping-key-id"`), + `$ stackit beta kms key import "my-key-id" --keyring-id "my-keyring-id" --wrapped-key "base64-encoded-wrapped-key-material" --wrapping-key-id "my-wrapping-key-id"`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/key/list/list.go b/internal/cmd/beta/kms/key/list/list.go index 2b909c5f9..56022871c 100644 --- a/internal/cmd/beta/kms/key/list/list.go +++ b/internal/cmd/beta/kms/key/list/list.go @@ -21,7 +21,7 @@ import ( ) const ( - keyRingIdFlag = "key-ring-id" + keyRingIdFlag = "keyring-id" ) type inputModel struct { @@ -37,11 +37,11 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Args: args.NoArgs, Example: examples.Build( examples.NewExample( - `List all KMS keys for the key ring "my-key-ring-id"`, - `$ stackit beta kms key list --key-ring-id "my-key-ring-id"`), + `List all KMS keys for the key ring "my-keyring-id"`, + `$ stackit beta kms key list --keyring-id "my-keyring-id"`), examples.NewExample( `List all KMS keys in JSON format`, - `$ stackit beta kms key list --key-ring-id "my-key-ring-id" --output-format json`), + `$ stackit beta kms key list --keyring-id "my-keyring-id" --output-format json`), ), RunE: func(cmd *cobra.Command, _ []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/key/restore/restore.go b/internal/cmd/beta/kms/key/restore/restore.go index e9454a760..3830ca957 100644 --- a/internal/cmd/beta/kms/key/restore/restore.go +++ b/internal/cmd/beta/kms/key/restore/restore.go @@ -24,7 +24,7 @@ import ( const ( keyIdArg = "KEY_ID" - keyRingIdFlag = "key-ring-id" + keyRingIdFlag = "keyring-id" ) type inputModel struct { @@ -41,8 +41,8 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Args: args.SingleArg(keyIdArg, utils.ValidateUUID), Example: examples.Build( examples.NewExample( - `Restore a KMS key "my-key-id" inside the key ring "my-key-ring-id" that was scheduled for deletion.`, - `$ stackit beta kms keyring restore "my-key-id" --key-ring-id "my-key-ring-id"`), + `Restore a KMS key "my-key-id" inside the key ring "my-keyring-id" that was scheduled for deletion.`, + `$ stackit beta kms keyring restore "my-key-id" --keyring-id "my-keyring-id"`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/key/rotate/rotate.go b/internal/cmd/beta/kms/key/rotate/rotate.go index 292ab4706..7888bea1a 100644 --- a/internal/cmd/beta/kms/key/rotate/rotate.go +++ b/internal/cmd/beta/kms/key/rotate/rotate.go @@ -24,7 +24,7 @@ import ( const ( keyIdArg = "KEY_ID" - keyRingIdFlag = "key-ring-id" + keyRingIdFlag = "keyring-id" ) type inputModel struct { @@ -41,8 +41,8 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Args: args.SingleArg(keyIdArg, utils.ValidateUUID), Example: examples.Build( examples.NewExample( - `Rotate a KMS key "my-key-id" and increase it's version inside the key ring "my-key-ring-id".`, - `$ stackit beta kms key rotate "my-key-id" --key-ring-id "my-key-ring-id"`), + `Rotate a KMS key "my-key-id" and increase it's version inside the key ring "my-keyring-id".`, + `$ stackit beta kms key rotate "my-key-id" --keyring-id "my-keyring-id"`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/keyring/delete/delete.go b/internal/cmd/beta/kms/keyring/delete/delete.go index 2ec6d2ef3..743c964f5 100644 --- a/internal/cmd/beta/kms/keyring/delete/delete.go +++ b/internal/cmd/beta/kms/keyring/delete/delete.go @@ -19,7 +19,7 @@ import ( ) const ( - keyRingIdArg = "KEY_RING_ID" + keyRingIdArg = "KEYRING-ID" ) type inputModel struct { @@ -35,8 +35,8 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Args: args.SingleArg(keyRingIdArg, utils.ValidateUUID), Example: examples.Build( examples.NewExample( - `Delete a KMS key ring with ID "my-key-ring-id"`, - `$ stackit beta kms keyring delete "my-key-ring-id"`), + `Delete a KMS key ring with ID "my-keyring-id"`, + `$ stackit beta kms keyring delete "my-keyring-id"`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/version/destroy/destroy.go b/internal/cmd/beta/kms/version/destroy/destroy.go index f999ad7a2..7adcaaafc 100644 --- a/internal/cmd/beta/kms/version/destroy/destroy.go +++ b/internal/cmd/beta/kms/version/destroy/destroy.go @@ -23,7 +23,7 @@ import ( const ( versionNumberArg = "VERSION_NUMBER" - keyRingIdFlag = "key-ring-id" + keyRingIdFlag = "keyring-id" keyIdFlag = "key-id" ) @@ -42,8 +42,8 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Args: args.SingleArg(versionNumberArg, nil), Example: examples.Build( examples.NewExample( - `Destroy key version "42" for the key "my-key-id" inside the key ring "my-key-ring-id"`, - `$ stackit beta kms version destroy 42 --key-id "my-key-id" --key-ring-id "my-key-ring-id"`), + `Destroy key version "42" for the key "my-key-id" inside the key ring "my-keyring-id"`, + `$ stackit beta kms version destroy 42 --key-id "my-key-id" --keyring-id "my-keyring-id"`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/version/disable/disable.go b/internal/cmd/beta/kms/version/disable/disable.go index a68ec054b..ebc90a0de 100644 --- a/internal/cmd/beta/kms/version/disable/disable.go +++ b/internal/cmd/beta/kms/version/disable/disable.go @@ -23,7 +23,7 @@ import ( const ( versionNumberArg = "VERSION_NUMBER" - keyRingIdFlag = "key-ring-id" + keyRingIdFlag = "keyring-id" keyIdFlag = "key-id" ) @@ -42,8 +42,8 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Args: args.SingleArg(versionNumberArg, nil), Example: examples.Build( examples.NewExample( - `Disable key version "42" for the key "my-key-id" inside the key ring "my-key-ring-id"`, - `$ stackit beta kms version disable 42 --key-id "my-key-id" --key-ring-id "my-key-ring-id"`), + `Disable key version "42" for the key "my-key-id" inside the key ring "my-keyring-id"`, + `$ stackit beta kms version disable 42 --key-id "my-key-id" --keyring-id "my-keyring-id"`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/version/enable/enable.go b/internal/cmd/beta/kms/version/enable/enable.go index 4dedf5fc1..25ccf7be2 100644 --- a/internal/cmd/beta/kms/version/enable/enable.go +++ b/internal/cmd/beta/kms/version/enable/enable.go @@ -25,7 +25,7 @@ import ( const ( versionNumberArg = "VERSION_NUMBER" - keyRingIdFlag = "key-ring-id" + keyRingIdFlag = "keyring-id" keyIdFlag = "key-id" ) @@ -44,8 +44,8 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Args: args.SingleArg(versionNumberArg, nil), Example: examples.Build( examples.NewExample( - `Enable key version "42" for the key "my-key-id" inside the key ring "my-key-ring-id"`, - `$ stackit beta kms version enable 42 --key-id "my-key-id" --key-ring-id "my-key-ring-id"`), + `Enable key version "42" for the key "my-key-id" inside the key ring "my-keyring-id"`, + `$ stackit beta kms version enable 42 --key-id "my-key-id" --keyring-id "my-keyring-id"`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/version/list/list.go b/internal/cmd/beta/kms/version/list/list.go index 7c970fde4..c73b2a949 100644 --- a/internal/cmd/beta/kms/version/list/list.go +++ b/internal/cmd/beta/kms/version/list/list.go @@ -21,7 +21,7 @@ import ( ) const ( - keyRingIdFlag = "key-ring-id" + keyRingIdFlag = "keyring-id" keyIdFlag = "key-id" ) @@ -39,11 +39,11 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Args: args.NoArgs, Example: examples.Build( examples.NewExample( - `List all key versions for the key "my-key-id" inside the key ring "my-key-ring-id"`, - `$ stackit beta kms version list --key-id "my-key-id" --key-ring-id "my-key-ring-id"`), + `List all key versions for the key "my-key-id" inside the key ring "my-keyring-id"`, + `$ stackit beta kms version list --key-id "my-key-id" --keyring-id "my-keyring-id"`), examples.NewExample( `List all key versions in JSON format`, - `$ stackit beta kms version list --key-id "my-key-id" --key-ring-id "my-key-ring-id" -o json`), + `$ stackit beta kms version list --key-id "my-key-id" --keyring-id "my-keyring-id" -o json`), ), RunE: func(cmd *cobra.Command, _ []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/version/restore/restore.go b/internal/cmd/beta/kms/version/restore/restore.go index 6acfe3960..e42701aca 100644 --- a/internal/cmd/beta/kms/version/restore/restore.go +++ b/internal/cmd/beta/kms/version/restore/restore.go @@ -23,7 +23,7 @@ import ( const ( versionNumberArg = "VERSION_NUMBER" - keyRingIdFlag = "key-ring-id" + keyRingIdFlag = "keyring-id" keyIdFlag = "key-id" ) @@ -42,8 +42,8 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Args: args.SingleArg(versionNumberArg, nil), Example: examples.Build( examples.NewExample( - `Restore key version "42" for the key "my-key-id" inside the key ring "my-key-ring-id"`, - `$ stackit beta kms version restore 42 --key-id "my-key-id" --key-ring-id "my-key-ring-id"`), + `Restore key version "42" for the key "my-key-id" inside the key ring "my-keyring-id"`, + `$ stackit beta kms version restore 42 --key-id "my-key-id" --keyring-id "my-keyring-id"`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/wrappingkey/create/create.go b/internal/cmd/beta/kms/wrappingkey/create/create.go index ca3515c98..84be0a1b9 100644 --- a/internal/cmd/beta/kms/wrappingkey/create/create.go +++ b/internal/cmd/beta/kms/wrappingkey/create/create.go @@ -23,7 +23,7 @@ import ( ) const ( - keyRingIdFlag = "key-ring-id" + keyRingIdFlag = "keyring-id" algorithmFlag = "algorithm" descriptionFlag = "description" @@ -52,10 +52,10 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Example: examples.Build( examples.NewExample( `Create a Symmetric KMS wrapping key`, - `$ stackit beta kms wrapping-key create --key-ring-id "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-wrapping-key-name" --purpose "wrap_symmetric_key" --protection "software"`), + `$ stackit beta kms wrapping-key create --keyring-id "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-wrapping-key-name" --purpose "wrap_symmetric_key" --protection "software"`), examples.NewExample( `Create an Asymmetric KMS wrapping key with a description`, - `$ stackit beta kms wrapping-key create --key-ring-id "my-keyring-id" --algorithm "hmac_sha256" --name "my-wrapping-key-name" --description "my-description" --purpose "wrap_asymmetric_key" --protection "software"`), + `$ stackit beta kms wrapping-key create --keyring-id "my-keyring-id" --algorithm "hmac_sha256" --name "my-wrapping-key-name" --description "my-description" --purpose "wrap_asymmetric_key" --protection "software"`), ), RunE: func(cmd *cobra.Command, _ []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/wrappingkey/delete/delete.go b/internal/cmd/beta/kms/wrappingkey/delete/delete.go index b1cca4d58..05e5e136b 100644 --- a/internal/cmd/beta/kms/wrappingkey/delete/delete.go +++ b/internal/cmd/beta/kms/wrappingkey/delete/delete.go @@ -22,7 +22,7 @@ import ( const ( wrappingKeyIdArg = "WRAPPING_KEY_ID" - keyRingIdFlag = "key-ring-id" + keyRingIdFlag = "keyring-id" ) type inputModel struct { @@ -39,8 +39,8 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Args: args.SingleArg(wrappingKeyIdArg, utils.ValidateUUID), Example: examples.Build( examples.NewExample( - `Delete a KMS wrapping key "my-wrapping-key-id" inside the key ring "my-key-ring-id"`, - `$ stackit beta kms wrapping-key delete "my-wrapping-key-id" --key-ring-id "my-key-ring-id"`), + `Delete a KMS wrapping key "my-wrapping-key-id" inside the key ring "my-keyring-id"`, + `$ stackit beta kms wrapping-key delete "my-wrapping-key-id" --keyring-id "my-keyring-id"`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/wrappingkey/list/list.go b/internal/cmd/beta/kms/wrappingkey/list/list.go index da113896c..9f0404970 100644 --- a/internal/cmd/beta/kms/wrappingkey/list/list.go +++ b/internal/cmd/beta/kms/wrappingkey/list/list.go @@ -21,7 +21,7 @@ import ( ) const ( - keyRingIdFlag = "key-ring-id" + keyRingIdFlag = "keyring-id" ) type inputModel struct { @@ -37,11 +37,11 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Args: args.NoArgs, Example: examples.Build( examples.NewExample( - `List all KMS wrapping keys for the key ring "my-key-ring-id"`, - `$ stackit beta kms wrapping-key list --key-ring-id "my-key-ring-id"`), + `List all KMS wrapping keys for the key ring "my-keyring-id"`, + `$ stackit beta kms wrapping-key list --keyring-id "my-keyring-id"`), examples.NewExample( `List all KMS wrapping keys in JSON format`, - `$ stackit beta kms wrappingkeys list --key-ring-id "my-key-ring-id" --output-format json`), + `$ stackit beta kms wrappingkeys list --keyring-id "my-keyring-id" --output-format json`), ), RunE: func(cmd *cobra.Command, _ []string) error { ctx := context.Background() From 78506a84a7f1ecd5093290a682150bee8e8aeefc Mon Sep 17 00:00:00 2001 From: Jan Sternagel Date: Tue, 21 Oct 2025 08:48:31 +0200 Subject: [PATCH 44/52] Added `EnumValues` to the flag options --- internal/cmd/beta/kms/key/create/create.go | 29 ++++++++++++++-- .../cmd/beta/kms/key/create/create_test.go | 2 +- internal/cmd/beta/kms/key/delete/delete.go | 1 + internal/cmd/beta/kms/key/list/list.go | 1 + internal/cmd/beta/kms/key/restore/restore.go | 1 + internal/cmd/beta/kms/key/rotate/rotate.go | 1 + .../cmd/beta/kms/wrappingkey/create/create.go | 34 +++++++++++++++---- .../kms/wrappingkey/create/create_test.go | 4 +-- 8 files changed, 61 insertions(+), 12 deletions(-) diff --git a/internal/cmd/beta/kms/key/create/create.go b/internal/cmd/beta/kms/key/create/create.go index 028192899..d2696a192 100644 --- a/internal/cmd/beta/kms/key/create/create.go +++ b/internal/cmd/beta/kms/key/create/create.go @@ -31,6 +31,10 @@ const ( importOnlyFlag = "import-only" purposeFlag = "purpose" protectionFlag = "protection" + + defaultAlgorithm = kms.ALGORITHM_RSA_2048_OAEP_SHA256 + defaultPurpose = kms.PURPOSE_ASYMMETRIC_ENCRYPT_DECRYPT + defaultProtection = kms.PROTECTION_SOFTWARE ) type inputModel struct { @@ -174,13 +178,32 @@ func outputResult(p *print.Printer, model *inputModel, resp *kms.Key) error { } func configureFlags(cmd *cobra.Command) { + // Algorithm + var algorithmFlagOptions []string + for _, val := range kms.AllowedAlgorithmEnumValues { + algorithmFlagOptions = append(algorithmFlagOptions, string(val)) + } + cmd.Flags().Var(flags.EnumFlag(false, string(defaultAlgorithm), algorithmFlagOptions...), algorithmFlag, fmt.Sprintf("En-/Decryption / signing algorithm. Possible values: %q", algorithmFlagOptions)) + + // Purpose + var purposeFlagOptions []string + for _, val := range kms.AllowedPurposeEnumValues { + purposeFlagOptions = append(purposeFlagOptions, string(val)) + } + cmd.Flags().Var(flags.EnumFlag(false, string(defaultPurpose), purposeFlagOptions...), purposeFlag, fmt.Sprintf("Purpose of the key. Possible values: %q", purposeFlagOptions)) + + // Protection + var protectionFlagOptions []string + for _, val := range kms.AllowedProtectionEnumValues { + protectionFlagOptions = append(protectionFlagOptions, string(val)) + } + cmd.Flags().Var(flags.EnumFlag(false, string(defaultProtection), protectionFlagOptions...), protectionFlag, fmt.Sprintf("The underlying system that is responsible for protecting the key material. Possible values: %q", purposeFlagOptions)) + + // All further non Enum Flags cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS key ring") - cmd.Flags().String(algorithmFlag, "", "En-/Decryption / signing algorithm") cmd.Flags().String(displayNameFlag, "", "The display name to distinguish multiple keys") cmd.Flags().String(descriptionFlag, "", "Optional description of the key") cmd.Flags().Bool(importOnlyFlag, false, "States whether versions can be created or only imported") - cmd.Flags().String(purposeFlag, "", "Purpose of the key. Enum: 'symmetric_encrypt_decrypt', 'asymmetric_encrypt_decrypt', 'message_authentication_code', 'asymmetric_sign_verify' ") - cmd.Flags().String(protectionFlag, "", "The underlying system that is responsible for protecting the key material. Value: 'software'") err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, algorithmFlag, purposeFlag, displayNameFlag, protectionFlag) cobra.CheckErr(err) diff --git a/internal/cmd/beta/kms/key/create/create_test.go b/internal/cmd/beta/kms/key/create/create_test.go index 14e0a84b1..f6c0a024e 100644 --- a/internal/cmd/beta/kms/key/create/create_test.go +++ b/internal/cmd/beta/kms/key/create/create_test.go @@ -17,7 +17,7 @@ import ( const ( testRegion = "eu01" - testAlgorithm = "some_rsa_2048" + testAlgorithm = "rsa_2048_oaep_sha256" testDisplayName = "my-key" testPurpose = "asymmetric_encrypt_decrypt" testDescription = "my key description" diff --git a/internal/cmd/beta/kms/key/delete/delete.go b/internal/cmd/beta/kms/key/delete/delete.go index 39ef637f1..c808a876a 100644 --- a/internal/cmd/beta/kms/key/delete/delete.go +++ b/internal/cmd/beta/kms/key/delete/delete.go @@ -118,6 +118,7 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClie func configureFlags(cmd *cobra.Command) { cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS Key Ring where the Key is stored") + err := flags.MarkFlagsRequired(cmd, keyRingIdFlag) cobra.CheckErr(err) } diff --git a/internal/cmd/beta/kms/key/list/list.go b/internal/cmd/beta/kms/key/list/list.go index 56022871c..0425e7ceb 100644 --- a/internal/cmd/beta/kms/key/list/list.go +++ b/internal/cmd/beta/kms/key/list/list.go @@ -93,6 +93,7 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClie func configureFlags(cmd *cobra.Command) { cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS Key Ring where the Key is stored") + err := flags.MarkFlagsRequired(cmd, keyRingIdFlag) cobra.CheckErr(err) } diff --git a/internal/cmd/beta/kms/key/restore/restore.go b/internal/cmd/beta/kms/key/restore/restore.go index 3830ca957..c6cb53164 100644 --- a/internal/cmd/beta/kms/key/restore/restore.go +++ b/internal/cmd/beta/kms/key/restore/restore.go @@ -117,6 +117,7 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClie func configureFlags(cmd *cobra.Command) { cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS Key Ring where the Key is stored") + err := flags.MarkFlagsRequired(cmd, keyRingIdFlag) cobra.CheckErr(err) } diff --git a/internal/cmd/beta/kms/key/rotate/rotate.go b/internal/cmd/beta/kms/key/rotate/rotate.go index 7888bea1a..faa8816ed 100644 --- a/internal/cmd/beta/kms/key/rotate/rotate.go +++ b/internal/cmd/beta/kms/key/rotate/rotate.go @@ -111,6 +111,7 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClie func configureFlags(cmd *cobra.Command) { cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS key Ring where the key is stored") + err := flags.MarkFlagsRequired(cmd, keyRingIdFlag) cobra.CheckErr(err) } diff --git a/internal/cmd/beta/kms/wrappingkey/create/create.go b/internal/cmd/beta/kms/wrappingkey/create/create.go index 84be0a1b9..9ac4b14af 100644 --- a/internal/cmd/beta/kms/wrappingkey/create/create.go +++ b/internal/cmd/beta/kms/wrappingkey/create/create.go @@ -30,6 +30,10 @@ const ( displayNameFlag = "name" purposeFlag = "purpose" protectionFlag = "protection" + + defaultWrappingAlgorithm = kms.WRAPPINGALGORITHM__2048_OAEP_SHA256 + defaultWrappingPurpose = kms.WRAPPINGPURPOSE_ASYMMETRIC_KEY + defaultProtection = kms.PROTECTION_SOFTWARE ) type inputModel struct { @@ -52,7 +56,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Example: examples.Build( examples.NewExample( `Create a Symmetric KMS wrapping key`, - `$ stackit beta kms wrapping-key create --keyring-id "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-wrapping-key-name" --purpose "wrap_symmetric_key" --protection "software"`), + `$ stackit beta kms wrapping-key create --keyring-id "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-wrapping-key-name" --purpose "wrap_asymmetric_key" --protection "software"`), examples.NewExample( `Create an Asymmetric KMS wrapping key with a description`, `$ stackit beta kms wrapping-key create --keyring-id "my-keyring-id" --algorithm "hmac_sha256" --name "my-wrapping-key-name" --description "my-description" --purpose "wrap_asymmetric_key" --protection "software"`), @@ -172,14 +176,32 @@ func outputResult(p *print.Printer, model *inputModel, resp *kms.WrappingKey) er } func configureFlags(cmd *cobra.Command) { + // Algorithm + var algorithmFlagOptions []string + for _, val := range kms.AllowedWrappingAlgorithmEnumValues { + algorithmFlagOptions = append(algorithmFlagOptions, string(val)) + } + cmd.Flags().Var(flags.EnumFlag(false, string(defaultWrappingAlgorithm), algorithmFlagOptions...), algorithmFlag, fmt.Sprintf("En-/Decryption / signing algorithm. Possible values: %q", algorithmFlagOptions)) + + // Purpose + var purposeFlagOptions []string + for _, val := range kms.AllowedWrappingPurposeEnumValues { + purposeFlagOptions = append(purposeFlagOptions, string(val)) + } + cmd.Flags().Var(flags.EnumFlag(false, string(defaultWrappingPurpose), purposeFlagOptions...), purposeFlag, fmt.Sprintf("Purpose of the wrapping key. Possible values: %q", purposeFlagOptions)) + + // Protection + // backend was deprectaed in /v1beta, but protection is a required attribute with value "software" + var protectionFlagOptions []string + for _, val := range kms.AllowedProtectionEnumValues { + protectionFlagOptions = append(protectionFlagOptions, string(val)) + } + cmd.Flags().Var(flags.EnumFlag(false, string(defaultProtection), protectionFlagOptions...), protectionFlag, fmt.Sprintf("The underlying system that is responsible for protecting the wrapping key material. Possible values: %q", purposeFlagOptions)) + + // All further non Enum Flags cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS key ring") - cmd.Flags().String(algorithmFlag, "", "En-/Decryption algorithm") cmd.Flags().String(displayNameFlag, "", "The display name to distinguish multiple wrapping keys") cmd.Flags().String(descriptionFlag, "", "Optional description of the wrapping key") - cmd.Flags().String(purposeFlag, "", "Purpose of the wrapping key. Enum: 'wrap_symmetric_key', 'wrap_asymmetric_key' ") - - // backend was deprectaed in /v1beta, but protection is a required attribute with value "software" - cmd.Flags().String(protectionFlag, "", "Protection of the wrapping key. Value: 'software' ") err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, algorithmFlag, purposeFlag, displayNameFlag, protectionFlag) cobra.CheckErr(err) diff --git a/internal/cmd/beta/kms/wrappingkey/create/create_test.go b/internal/cmd/beta/kms/wrappingkey/create/create_test.go index f92cee851..15616c322 100644 --- a/internal/cmd/beta/kms/wrappingkey/create/create_test.go +++ b/internal/cmd/beta/kms/wrappingkey/create/create_test.go @@ -17,9 +17,9 @@ import ( const ( testRegion = "eu01" - testAlgorithm = "some_rsa_2048" + testAlgorithm = "rsa_2048_oaep_sha256" testDisplayName = "my-key" - testPurpose = "asymmetric_encrypt_decrypt" + testPurpose = "wrap_asymmetric_key" testDescription = "my key description" testProtection = "software" ) From 888034822348781197da3bca8b48264b20142003 Mon Sep 17 00:00:00 2001 From: Jan Sternagel Date: Tue, 21 Oct 2025 09:00:05 +0200 Subject: [PATCH 45/52] argument ID always in uppercase & typo fix --- docs/stackit_beta_kms_key_create.md | 10 +++++----- docs/stackit_beta_kms_key_delete.md | 4 ++-- docs/stackit_beta_kms_key_import.md | 4 ++-- docs/stackit_beta_kms_key_list.md | 6 +++--- docs/stackit_beta_kms_key_restore.md | 4 ++-- docs/stackit_beta_kms_key_rotate.md | 4 ++-- docs/stackit_beta_kms_keyring_delete.md | 4 ++-- docs/stackit_beta_kms_version_destroy.md | 4 ++-- docs/stackit_beta_kms_version_disable.md | 6 +++--- docs/stackit_beta_kms_version_enable.md | 4 ++-- docs/stackit_beta_kms_version_list.md | 6 +++--- docs/stackit_beta_kms_version_restore.md | 4 ++-- docs/stackit_beta_kms_wrapping-key_create.md | 10 +++++----- docs/stackit_beta_kms_wrapping-key_delete.md | 4 ++-- docs/stackit_beta_kms_wrapping-key_list.md | 6 +++--- internal/cmd/beta/kms/key/create/create.go | 4 ++-- internal/cmd/beta/kms/key/delete/delete.go | 4 ++-- internal/cmd/beta/kms/key/importKey/importKey.go | 4 ++-- internal/cmd/beta/kms/key/list/list.go | 6 +++--- internal/cmd/beta/kms/key/restore/restore.go | 4 ++-- internal/cmd/beta/kms/key/rotate/rotate.go | 4 ++-- internal/cmd/beta/kms/keyring/delete/delete.go | 4 ++-- internal/cmd/beta/kms/version/destroy/destroy.go | 4 ++-- internal/cmd/beta/kms/version/disable/disable.go | 6 +++--- internal/cmd/beta/kms/version/enable/enable.go | 4 ++-- internal/cmd/beta/kms/version/list/list.go | 6 +++--- internal/cmd/beta/kms/version/restore/restore.go | 4 ++-- internal/cmd/beta/kms/wrappingkey/create/create.go | 4 ++-- internal/cmd/beta/kms/wrappingkey/delete/delete.go | 4 ++-- internal/cmd/beta/kms/wrappingkey/list/list.go | 6 +++--- 30 files changed, 74 insertions(+), 74 deletions(-) diff --git a/docs/stackit_beta_kms_key_create.md b/docs/stackit_beta_kms_key_create.md index ba19a6145..e7e59b6d9 100644 --- a/docs/stackit_beta_kms_key_create.md +++ b/docs/stackit_beta_kms_key_create.md @@ -14,23 +14,23 @@ stackit beta kms key create [flags] ``` Create a Symmetric KMS key - $ stackit beta kms key create --keyring-id "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-key-name" --purpose "asymmetric_encrypt_decrypt" --protection "software" + $ stackit beta kms key create --keyring-id "MY_KEYRING_ID" --algorithm "rsa_2048_oaep_sha256" --name "my-key-name" --purpose "asymmetric_encrypt_decrypt" --protection "software" Create a Message Authentication KMS key - $ stackit beta kms key create --keyring-id "my-keyring-id" --algorithm "hmac_sha512" --name "my-key-name" --purpose "message_authentication_code" --protection "software" + $ stackit beta kms key create --keyring-id "MY_KEYRING_ID" --algorithm "hmac_sha512" --name "my-key-name" --purpose "message_authentication_code" --protection "software" ``` ### Options ``` - --algorithm string En-/Decryption / signing algorithm + --algorithm string En-/Decryption / signing algorithm. Possible values: ["aes_256_gcm" "rsa_2048_oaep_sha256" "rsa_3072_oaep_sha256" "rsa_4096_oaep_sha256" "rsa_4096_oaep_sha512" "hmac_sha256" "hmac_sha384" "hmac_sha512" "ecdsa_p256_sha256" "ecdsa_p384_sha384" "ecdsa_p521_sha512"] (default "rsa_2048_oaep_sha256") --description string Optional description of the key -h, --help Help for "stackit beta kms key create" --import-only States whether versions can be created or only imported --keyring-id string ID of the KMS key ring --name string The display name to distinguish multiple keys - --protection string The underlying system that is responsible for protecting the key material. Value: 'software' - --purpose string Purpose of the key. Enum: 'symmetric_encrypt_decrypt', 'asymmetric_encrypt_decrypt', 'message_authentication_code', 'asymmetric_sign_verify' + --protection string The underlying system that is responsible for protecting the key material. Possible values: ["symmetric_encrypt_decrypt" "asymmetric_encrypt_decrypt" "message_authentication_code" "asymmetric_sign_verify"] (default "software") + --purpose string Purpose of the key. Possible values: ["symmetric_encrypt_decrypt" "asymmetric_encrypt_decrypt" "message_authentication_code" "asymmetric_sign_verify"] (default "asymmetric_encrypt_decrypt") ``` ### Options inherited from parent commands diff --git a/docs/stackit_beta_kms_key_delete.md b/docs/stackit_beta_kms_key_delete.md index 90e55d491..86117ce48 100644 --- a/docs/stackit_beta_kms_key_delete.md +++ b/docs/stackit_beta_kms_key_delete.md @@ -13,8 +13,8 @@ stackit beta kms key delete KEY_ID [flags] ### Examples ``` - Delete a KMS key "my-key-id" inside the key ring "my-keyring-id" - $ stackit beta kms key delete "my-key-id" --keyring-id "my-keyring-id" + Delete a KMS key "MY_KEY_ID" inside the key ring "MY_KEYRING_ID" + $ stackit beta kms key delete "MY_KEY_ID" --keyring-id "MY_KEYRING_ID" ``` ### Options diff --git a/docs/stackit_beta_kms_key_import.md b/docs/stackit_beta_kms_key_import.md index 4cc9c5c3b..7a683d6a7 100644 --- a/docs/stackit_beta_kms_key_import.md +++ b/docs/stackit_beta_kms_key_import.md @@ -13,8 +13,8 @@ stackit beta kms key import KEY_ID [flags] ### Examples ``` - Import a new version for the given KMS key "my-key-id" - $ stackit beta kms key import "my-key-id" --keyring-id "my-keyring-id" --wrapped-key "base64-encoded-wrapped-key-material" --wrapping-key-id "my-wrapping-key-id" + Import a new version for the given KMS key "MY_KEY_ID" + $ stackit beta kms key import "MY_KEY_ID" --keyring-id "MY_KEYRING_ID" --wrapped-key "base64-encoded-wrapped-key-material" --wrapping-key-id "MY_WRAPPING_KEY_ID" ``` ### Options diff --git a/docs/stackit_beta_kms_key_list.md b/docs/stackit_beta_kms_key_list.md index 533b15248..0cf81b773 100644 --- a/docs/stackit_beta_kms_key_list.md +++ b/docs/stackit_beta_kms_key_list.md @@ -13,11 +13,11 @@ stackit beta kms key list [flags] ### Examples ``` - List all KMS keys for the key ring "my-keyring-id" - $ stackit beta kms key list --keyring-id "my-keyring-id" + List all KMS keys for the key ring "MY_KEYRING_ID" + $ stackit beta kms key list --keyring-id "MY_KEYRING_ID" List all KMS keys in JSON format - $ stackit beta kms key list --keyring-id "my-keyring-id" --output-format json + $ stackit beta kms key list --keyring-id "MY_KEYRING_ID" --output-format json ``` ### Options diff --git a/docs/stackit_beta_kms_key_restore.md b/docs/stackit_beta_kms_key_restore.md index d0f79c400..e03d236b1 100644 --- a/docs/stackit_beta_kms_key_restore.md +++ b/docs/stackit_beta_kms_key_restore.md @@ -13,8 +13,8 @@ stackit beta kms key restore KEY_ID [flags] ### Examples ``` - Restore a KMS key "my-key-id" inside the key ring "my-keyring-id" that was scheduled for deletion. - $ stackit beta kms keyring restore "my-key-id" --keyring-id "my-keyring-id" + Restore a KMS key "MY_KEY_ID" inside the key ring "MY_KEYRING_ID" that was scheduled for deletion. + $ stackit beta kms keyring restore "MY_KEY_ID" --keyring-id "MY_KEYRING_ID" ``` ### Options diff --git a/docs/stackit_beta_kms_key_rotate.md b/docs/stackit_beta_kms_key_rotate.md index 1f04c789e..4f4d7029e 100644 --- a/docs/stackit_beta_kms_key_rotate.md +++ b/docs/stackit_beta_kms_key_rotate.md @@ -13,8 +13,8 @@ stackit beta kms key rotate KEY_ID [flags] ### Examples ``` - Rotate a KMS key "my-key-id" and increase it's version inside the key ring "my-keyring-id". - $ stackit beta kms key rotate "my-key-id" --keyring-id "my-keyring-id" + Rotate a KMS key "MY_KEY_ID" and increase it's version inside the key ring "MY_KEYRING_ID". + $ stackit beta kms key rotate "MY_KEY_ID" --keyring-id "MY_KEYRING_ID" ``` ### Options diff --git a/docs/stackit_beta_kms_keyring_delete.md b/docs/stackit_beta_kms_keyring_delete.md index 57c190d3f..d5230f353 100644 --- a/docs/stackit_beta_kms_keyring_delete.md +++ b/docs/stackit_beta_kms_keyring_delete.md @@ -13,8 +13,8 @@ stackit beta kms keyring delete KEYRING-ID [flags] ### Examples ``` - Delete a KMS key ring with ID "my-keyring-id" - $ stackit beta kms keyring delete "my-keyring-id" + Delete a KMS key ring with ID "MY_KEYRING_ID" + $ stackit beta kms keyring delete "MY_KEYRING_ID" ``` ### Options diff --git a/docs/stackit_beta_kms_version_destroy.md b/docs/stackit_beta_kms_version_destroy.md index 8a189ecf2..e330b50d3 100644 --- a/docs/stackit_beta_kms_version_destroy.md +++ b/docs/stackit_beta_kms_version_destroy.md @@ -13,8 +13,8 @@ stackit beta kms version destroy VERSION_NUMBER [flags] ### Examples ``` - Destroy key version "42" for the key "my-key-id" inside the key ring "my-keyring-id" - $ stackit beta kms version destroy 42 --key-id "my-key-id" --keyring-id "my-keyring-id" + Destroy key version "42" for the key "MY_KEY_ID" inside the key ring "MY_KEYRING_ID" + $ stackit beta kms version destroy 42 --key-id "MY_KEY_ID" --keyring-id "MY_KEYRING_ID" ``` ### Options diff --git a/docs/stackit_beta_kms_version_disable.md b/docs/stackit_beta_kms_version_disable.md index ca560e198..114c2996a 100644 --- a/docs/stackit_beta_kms_version_disable.md +++ b/docs/stackit_beta_kms_version_disable.md @@ -13,15 +13,15 @@ stackit beta kms version disable VERSION_NUMBER [flags] ### Examples ``` - Disable key version "42" for the key "my-key-id" inside the key ring "my-keyring-id" - $ stackit beta kms version disable 42 --key-id "my-key-id" --keyring-id "my-keyring-id" + Disable key version "42" for the key "MY_KEY_ID" inside the key ring "MY_KEYRING_ID" + $ stackit beta kms version disable 42 --key-id "MY_KEY_ID" --keyring-id "MY_KEYRING_ID" ``` ### Options ``` -h, --help Help for "stackit beta kms version disable" - --key-id string ID of the rey + --key-id string ID of the key --keyring-id string ID of the KMS key ring ``` diff --git a/docs/stackit_beta_kms_version_enable.md b/docs/stackit_beta_kms_version_enable.md index 46d23bec0..9b992ecac 100644 --- a/docs/stackit_beta_kms_version_enable.md +++ b/docs/stackit_beta_kms_version_enable.md @@ -13,8 +13,8 @@ stackit beta kms version enable VERSION_NUMBER [flags] ### Examples ``` - Enable key version "42" for the key "my-key-id" inside the key ring "my-keyring-id" - $ stackit beta kms version enable 42 --key-id "my-key-id" --keyring-id "my-keyring-id" + Enable key version "42" for the key "MY_KEY_ID" inside the key ring "MY_KEYRING_ID" + $ stackit beta kms version enable 42 --key-id "MY_KEY_ID" --keyring-id "MY_KEYRING_ID" ``` ### Options diff --git a/docs/stackit_beta_kms_version_list.md b/docs/stackit_beta_kms_version_list.md index bd4a96747..d1950d700 100644 --- a/docs/stackit_beta_kms_version_list.md +++ b/docs/stackit_beta_kms_version_list.md @@ -13,11 +13,11 @@ stackit beta kms version list [flags] ### Examples ``` - List all key versions for the key "my-key-id" inside the key ring "my-keyring-id" - $ stackit beta kms version list --key-id "my-key-id" --keyring-id "my-keyring-id" + List all key versions for the key "MY_KEY_ID" inside the key ring "MY_KEYRING_ID" + $ stackit beta kms version list --key-id "MY_KEY_ID" --keyring-id "MY_KEYRING_ID" List all key versions in JSON format - $ stackit beta kms version list --key-id "my-key-id" --keyring-id "my-keyring-id" -o json + $ stackit beta kms version list --key-id "MY_KEY_ID" --keyring-id "MY_KEYRING_ID" -o json ``` ### Options diff --git a/docs/stackit_beta_kms_version_restore.md b/docs/stackit_beta_kms_version_restore.md index 8b2bc84cc..ae3dd4a73 100644 --- a/docs/stackit_beta_kms_version_restore.md +++ b/docs/stackit_beta_kms_version_restore.md @@ -13,8 +13,8 @@ stackit beta kms version restore VERSION_NUMBER [flags] ### Examples ``` - Restore key version "42" for the key "my-key-id" inside the key ring "my-keyring-id" - $ stackit beta kms version restore 42 --key-id "my-key-id" --keyring-id "my-keyring-id" + Restore key version "42" for the key "MY_KEY_ID" inside the key ring "MY_KEYRING_ID" + $ stackit beta kms version restore 42 --key-id "MY_KEY_ID" --keyring-id "MY_KEYRING_ID" ``` ### Options diff --git a/docs/stackit_beta_kms_wrapping-key_create.md b/docs/stackit_beta_kms_wrapping-key_create.md index 971eb6025..e6b7697fb 100644 --- a/docs/stackit_beta_kms_wrapping-key_create.md +++ b/docs/stackit_beta_kms_wrapping-key_create.md @@ -14,22 +14,22 @@ stackit beta kms wrapping-key create [flags] ``` Create a Symmetric KMS wrapping key - $ stackit beta kms wrapping-key create --keyring-id "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-wrapping-key-name" --purpose "wrap_symmetric_key" --protection "software" + $ stackit beta kms wrapping-key create --keyring-id "MY_KEYRING_ID" --algorithm "rsa_2048_oaep_sha256" --name "my-wrapping-key-name" --purpose "wrap_asymmetric_key" --protection "software" Create an Asymmetric KMS wrapping key with a description - $ stackit beta kms wrapping-key create --keyring-id "my-keyring-id" --algorithm "hmac_sha256" --name "my-wrapping-key-name" --description "my-description" --purpose "wrap_asymmetric_key" --protection "software" + $ stackit beta kms wrapping-key create --keyring-id "MY_KEYRING_ID" --algorithm "hmac_sha256" --name "my-wrapping-key-name" --description "my-description" --purpose "wrap_asymmetric_key" --protection "software" ``` ### Options ``` - --algorithm string En-/Decryption algorithm + --algorithm string En-/Decryption / signing algorithm. Possible values: ["rsa_2048_oaep_sha256" "rsa_3072_oaep_sha256" "rsa_4096_oaep_sha256" "rsa_4096_oaep_sha512" "rsa_2048_oaep_sha256_aes_256_key_wrap" "rsa_3072_oaep_sha256_aes_256_key_wrap" "rsa_4096_oaep_sha256_aes_256_key_wrap" "rsa_4096_oaep_sha512_aes_256_key_wrap"] (default "rsa_2048_oaep_sha256") --description string Optional description of the wrapping key -h, --help Help for "stackit beta kms wrapping-key create" --keyring-id string ID of the KMS key ring --name string The display name to distinguish multiple wrapping keys - --protection string Protection of the wrapping key. Value: 'software' - --purpose string Purpose of the wrapping key. Enum: 'wrap_symmetric_key', 'wrap_asymmetric_key' + --protection string The underlying system that is responsible for protecting the wrapping key material. Possible values: ["wrap_symmetric_key" "wrap_asymmetric_key"] (default "software") + --purpose string Purpose of the wrapping key. Possible values: ["wrap_symmetric_key" "wrap_asymmetric_key"] (default "wrap_asymmetric_key") ``` ### Options inherited from parent commands diff --git a/docs/stackit_beta_kms_wrapping-key_delete.md b/docs/stackit_beta_kms_wrapping-key_delete.md index 8e5204783..dce6cf824 100644 --- a/docs/stackit_beta_kms_wrapping-key_delete.md +++ b/docs/stackit_beta_kms_wrapping-key_delete.md @@ -13,8 +13,8 @@ stackit beta kms wrapping-key delete WRAPPING_KEY_ID [flags] ### Examples ``` - Delete a KMS wrapping key "my-wrapping-key-id" inside the key ring "my-keyring-id" - $ stackit beta kms wrapping-key delete "my-wrapping-key-id" --keyring-id "my-keyring-id" + Delete a KMS wrapping key "MY_WRAPPING_KEY_ID" inside the key ring "MY_KEYRING_ID" + $ stackit beta kms wrapping-key delete "MY_WRAPPING_KEY_ID" --keyring-id "MY_KEYRING_ID" ``` ### Options diff --git a/docs/stackit_beta_kms_wrapping-key_list.md b/docs/stackit_beta_kms_wrapping-key_list.md index a26f303c2..ca93dcae2 100644 --- a/docs/stackit_beta_kms_wrapping-key_list.md +++ b/docs/stackit_beta_kms_wrapping-key_list.md @@ -13,11 +13,11 @@ stackit beta kms wrapping-key list [flags] ### Examples ``` - List all KMS wrapping keys for the key ring "my-keyring-id" - $ stackit beta kms wrapping-key list --keyring-id "my-keyring-id" + List all KMS wrapping keys for the key ring "MY_KEYRING_ID" + $ stackit beta kms wrapping-key list --keyring-id "MY_KEYRING_ID" List all KMS wrapping keys in JSON format - $ stackit beta kms wrappingkeys list --keyring-id "my-keyring-id" --output-format json + $ stackit beta kms wrappingkeys list --keyring-id "MY_KEYRING_ID" --output-format json ``` ### Options diff --git a/internal/cmd/beta/kms/key/create/create.go b/internal/cmd/beta/kms/key/create/create.go index d2696a192..1443dba6a 100644 --- a/internal/cmd/beta/kms/key/create/create.go +++ b/internal/cmd/beta/kms/key/create/create.go @@ -58,10 +58,10 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Example: examples.Build( examples.NewExample( `Create a Symmetric KMS key`, - `$ stackit beta kms key create --keyring-id "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-key-name" --purpose "asymmetric_encrypt_decrypt" --protection "software"`), + `$ stackit beta kms key create --keyring-id "MY_KEYRING_ID" --algorithm "rsa_2048_oaep_sha256" --name "my-key-name" --purpose "asymmetric_encrypt_decrypt" --protection "software"`), examples.NewExample( `Create a Message Authentication KMS key`, - `$ stackit beta kms key create --keyring-id "my-keyring-id" --algorithm "hmac_sha512" --name "my-key-name" --purpose "message_authentication_code" --protection "software"`), + `$ stackit beta kms key create --keyring-id "MY_KEYRING_ID" --algorithm "hmac_sha512" --name "my-key-name" --purpose "message_authentication_code" --protection "software"`), ), RunE: func(cmd *cobra.Command, _ []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/key/delete/delete.go b/internal/cmd/beta/kms/key/delete/delete.go index c808a876a..0f7915212 100644 --- a/internal/cmd/beta/kms/key/delete/delete.go +++ b/internal/cmd/beta/kms/key/delete/delete.go @@ -41,8 +41,8 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Args: args.SingleArg(keyIdArg, utils.ValidateUUID), Example: examples.Build( examples.NewExample( - `Delete a KMS key "my-key-id" inside the key ring "my-keyring-id"`, - `$ stackit beta kms key delete "my-key-id" --keyring-id "my-keyring-id"`), + `Delete a KMS key "MY_KEY_ID" inside the key ring "MY_KEYRING_ID"`, + `$ stackit beta kms key delete "MY_KEY_ID" --keyring-id "MY_KEYRING_ID"`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/key/importKey/importKey.go b/internal/cmd/beta/kms/key/importKey/importKey.go index 096013b7a..06f26c807 100644 --- a/internal/cmd/beta/kms/key/importKey/importKey.go +++ b/internal/cmd/beta/kms/key/importKey/importKey.go @@ -46,8 +46,8 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Args: args.SingleArg(keyIdArg, utils.ValidateUUID), Example: examples.Build( examples.NewExample( - `Import a new version for the given KMS key "my-key-id"`, - `$ stackit beta kms key import "my-key-id" --keyring-id "my-keyring-id" --wrapped-key "base64-encoded-wrapped-key-material" --wrapping-key-id "my-wrapping-key-id"`), + `Import a new version for the given KMS key "MY_KEY_ID"`, + `$ stackit beta kms key import "MY_KEY_ID" --keyring-id "MY_KEYRING_ID" --wrapped-key "base64-encoded-wrapped-key-material" --wrapping-key-id "MY_WRAPPING_KEY_ID"`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/key/list/list.go b/internal/cmd/beta/kms/key/list/list.go index 0425e7ceb..4bc78e29a 100644 --- a/internal/cmd/beta/kms/key/list/list.go +++ b/internal/cmd/beta/kms/key/list/list.go @@ -37,11 +37,11 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Args: args.NoArgs, Example: examples.Build( examples.NewExample( - `List all KMS keys for the key ring "my-keyring-id"`, - `$ stackit beta kms key list --keyring-id "my-keyring-id"`), + `List all KMS keys for the key ring "MY_KEYRING_ID"`, + `$ stackit beta kms key list --keyring-id "MY_KEYRING_ID"`), examples.NewExample( `List all KMS keys in JSON format`, - `$ stackit beta kms key list --keyring-id "my-keyring-id" --output-format json`), + `$ stackit beta kms key list --keyring-id "MY_KEYRING_ID" --output-format json`), ), RunE: func(cmd *cobra.Command, _ []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/key/restore/restore.go b/internal/cmd/beta/kms/key/restore/restore.go index c6cb53164..519c2ebd4 100644 --- a/internal/cmd/beta/kms/key/restore/restore.go +++ b/internal/cmd/beta/kms/key/restore/restore.go @@ -41,8 +41,8 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Args: args.SingleArg(keyIdArg, utils.ValidateUUID), Example: examples.Build( examples.NewExample( - `Restore a KMS key "my-key-id" inside the key ring "my-keyring-id" that was scheduled for deletion.`, - `$ stackit beta kms keyring restore "my-key-id" --keyring-id "my-keyring-id"`), + `Restore a KMS key "MY_KEY_ID" inside the key ring "MY_KEYRING_ID" that was scheduled for deletion.`, + `$ stackit beta kms keyring restore "MY_KEY_ID" --keyring-id "MY_KEYRING_ID"`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/key/rotate/rotate.go b/internal/cmd/beta/kms/key/rotate/rotate.go index faa8816ed..0579c4940 100644 --- a/internal/cmd/beta/kms/key/rotate/rotate.go +++ b/internal/cmd/beta/kms/key/rotate/rotate.go @@ -41,8 +41,8 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Args: args.SingleArg(keyIdArg, utils.ValidateUUID), Example: examples.Build( examples.NewExample( - `Rotate a KMS key "my-key-id" and increase it's version inside the key ring "my-keyring-id".`, - `$ stackit beta kms key rotate "my-key-id" --keyring-id "my-keyring-id"`), + `Rotate a KMS key "MY_KEY_ID" and increase it's version inside the key ring "MY_KEYRING_ID".`, + `$ stackit beta kms key rotate "MY_KEY_ID" --keyring-id "MY_KEYRING_ID"`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/keyring/delete/delete.go b/internal/cmd/beta/kms/keyring/delete/delete.go index 743c964f5..307729745 100644 --- a/internal/cmd/beta/kms/keyring/delete/delete.go +++ b/internal/cmd/beta/kms/keyring/delete/delete.go @@ -35,8 +35,8 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Args: args.SingleArg(keyRingIdArg, utils.ValidateUUID), Example: examples.Build( examples.NewExample( - `Delete a KMS key ring with ID "my-keyring-id"`, - `$ stackit beta kms keyring delete "my-keyring-id"`), + `Delete a KMS key ring with ID "MY_KEYRING_ID"`, + `$ stackit beta kms keyring delete "MY_KEYRING_ID"`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/version/destroy/destroy.go b/internal/cmd/beta/kms/version/destroy/destroy.go index 7adcaaafc..d7853e912 100644 --- a/internal/cmd/beta/kms/version/destroy/destroy.go +++ b/internal/cmd/beta/kms/version/destroy/destroy.go @@ -42,8 +42,8 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Args: args.SingleArg(versionNumberArg, nil), Example: examples.Build( examples.NewExample( - `Destroy key version "42" for the key "my-key-id" inside the key ring "my-keyring-id"`, - `$ stackit beta kms version destroy 42 --key-id "my-key-id" --keyring-id "my-keyring-id"`), + `Destroy key version "42" for the key "MY_KEY_ID" inside the key ring "MY_KEYRING_ID"`, + `$ stackit beta kms version destroy 42 --key-id "MY_KEY_ID" --keyring-id "MY_KEYRING_ID"`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/version/disable/disable.go b/internal/cmd/beta/kms/version/disable/disable.go index ebc90a0de..bba692072 100644 --- a/internal/cmd/beta/kms/version/disable/disable.go +++ b/internal/cmd/beta/kms/version/disable/disable.go @@ -42,8 +42,8 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Args: args.SingleArg(versionNumberArg, nil), Example: examples.Build( examples.NewExample( - `Disable key version "42" for the key "my-key-id" inside the key ring "my-keyring-id"`, - `$ stackit beta kms version disable 42 --key-id "my-key-id" --keyring-id "my-keyring-id"`), + `Disable key version "42" for the key "MY_KEY_ID" inside the key ring "MY_KEYRING_ID"`, + `$ stackit beta kms version disable 42 --key-id "MY_KEY_ID" --keyring-id "MY_KEYRING_ID"`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() @@ -115,7 +115,7 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClie func configureFlags(cmd *cobra.Command) { cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS key ring") - cmd.Flags().Var(flags.UUIDFlag(), keyIdFlag, "ID of the rey") + cmd.Flags().Var(flags.UUIDFlag(), keyIdFlag, "ID of the key") err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, keyIdFlag) cobra.CheckErr(err) diff --git a/internal/cmd/beta/kms/version/enable/enable.go b/internal/cmd/beta/kms/version/enable/enable.go index 25ccf7be2..a8eb35e46 100644 --- a/internal/cmd/beta/kms/version/enable/enable.go +++ b/internal/cmd/beta/kms/version/enable/enable.go @@ -44,8 +44,8 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Args: args.SingleArg(versionNumberArg, nil), Example: examples.Build( examples.NewExample( - `Enable key version "42" for the key "my-key-id" inside the key ring "my-keyring-id"`, - `$ stackit beta kms version enable 42 --key-id "my-key-id" --keyring-id "my-keyring-id"`), + `Enable key version "42" for the key "MY_KEY_ID" inside the key ring "MY_KEYRING_ID"`, + `$ stackit beta kms version enable 42 --key-id "MY_KEY_ID" --keyring-id "MY_KEYRING_ID"`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/version/list/list.go b/internal/cmd/beta/kms/version/list/list.go index c73b2a949..21a618e6e 100644 --- a/internal/cmd/beta/kms/version/list/list.go +++ b/internal/cmd/beta/kms/version/list/list.go @@ -39,11 +39,11 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Args: args.NoArgs, Example: examples.Build( examples.NewExample( - `List all key versions for the key "my-key-id" inside the key ring "my-keyring-id"`, - `$ stackit beta kms version list --key-id "my-key-id" --keyring-id "my-keyring-id"`), + `List all key versions for the key "MY_KEY_ID" inside the key ring "MY_KEYRING_ID"`, + `$ stackit beta kms version list --key-id "MY_KEY_ID" --keyring-id "MY_KEYRING_ID"`), examples.NewExample( `List all key versions in JSON format`, - `$ stackit beta kms version list --key-id "my-key-id" --keyring-id "my-keyring-id" -o json`), + `$ stackit beta kms version list --key-id "MY_KEY_ID" --keyring-id "MY_KEYRING_ID" -o json`), ), RunE: func(cmd *cobra.Command, _ []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/version/restore/restore.go b/internal/cmd/beta/kms/version/restore/restore.go index e42701aca..fea850258 100644 --- a/internal/cmd/beta/kms/version/restore/restore.go +++ b/internal/cmd/beta/kms/version/restore/restore.go @@ -42,8 +42,8 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Args: args.SingleArg(versionNumberArg, nil), Example: examples.Build( examples.NewExample( - `Restore key version "42" for the key "my-key-id" inside the key ring "my-keyring-id"`, - `$ stackit beta kms version restore 42 --key-id "my-key-id" --keyring-id "my-keyring-id"`), + `Restore key version "42" for the key "MY_KEY_ID" inside the key ring "MY_KEYRING_ID"`, + `$ stackit beta kms version restore 42 --key-id "MY_KEY_ID" --keyring-id "MY_KEYRING_ID"`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/wrappingkey/create/create.go b/internal/cmd/beta/kms/wrappingkey/create/create.go index 9ac4b14af..db3884ae9 100644 --- a/internal/cmd/beta/kms/wrappingkey/create/create.go +++ b/internal/cmd/beta/kms/wrappingkey/create/create.go @@ -56,10 +56,10 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Example: examples.Build( examples.NewExample( `Create a Symmetric KMS wrapping key`, - `$ stackit beta kms wrapping-key create --keyring-id "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "my-wrapping-key-name" --purpose "wrap_asymmetric_key" --protection "software"`), + `$ stackit beta kms wrapping-key create --keyring-id "MY_KEYRING_ID" --algorithm "rsa_2048_oaep_sha256" --name "my-wrapping-key-name" --purpose "wrap_asymmetric_key" --protection "software"`), examples.NewExample( `Create an Asymmetric KMS wrapping key with a description`, - `$ stackit beta kms wrapping-key create --keyring-id "my-keyring-id" --algorithm "hmac_sha256" --name "my-wrapping-key-name" --description "my-description" --purpose "wrap_asymmetric_key" --protection "software"`), + `$ stackit beta kms wrapping-key create --keyring-id "MY_KEYRING_ID" --algorithm "hmac_sha256" --name "my-wrapping-key-name" --description "my-description" --purpose "wrap_asymmetric_key" --protection "software"`), ), RunE: func(cmd *cobra.Command, _ []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/wrappingkey/delete/delete.go b/internal/cmd/beta/kms/wrappingkey/delete/delete.go index 05e5e136b..9151c2563 100644 --- a/internal/cmd/beta/kms/wrappingkey/delete/delete.go +++ b/internal/cmd/beta/kms/wrappingkey/delete/delete.go @@ -39,8 +39,8 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Args: args.SingleArg(wrappingKeyIdArg, utils.ValidateUUID), Example: examples.Build( examples.NewExample( - `Delete a KMS wrapping key "my-wrapping-key-id" inside the key ring "my-keyring-id"`, - `$ stackit beta kms wrapping-key delete "my-wrapping-key-id" --keyring-id "my-keyring-id"`), + `Delete a KMS wrapping key "MY_WRAPPING_KEY_ID" inside the key ring "MY_KEYRING_ID"`, + `$ stackit beta kms wrapping-key delete "MY_WRAPPING_KEY_ID" --keyring-id "MY_KEYRING_ID"`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/wrappingkey/list/list.go b/internal/cmd/beta/kms/wrappingkey/list/list.go index 9f0404970..a71665952 100644 --- a/internal/cmd/beta/kms/wrappingkey/list/list.go +++ b/internal/cmd/beta/kms/wrappingkey/list/list.go @@ -37,11 +37,11 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Args: args.NoArgs, Example: examples.Build( examples.NewExample( - `List all KMS wrapping keys for the key ring "my-keyring-id"`, - `$ stackit beta kms wrapping-key list --keyring-id "my-keyring-id"`), + `List all KMS wrapping keys for the key ring "MY_KEYRING_ID"`, + `$ stackit beta kms wrapping-key list --keyring-id "MY_KEYRING_ID"`), examples.NewExample( `List all KMS wrapping keys in JSON format`, - `$ stackit beta kms wrappingkeys list --keyring-id "my-keyring-id" --output-format json`), + `$ stackit beta kms wrappingkeys list --keyring-id "MY_KEYRING_ID" --output-format json`), ), RunE: func(cmd *cobra.Command, _ []string) error { ctx := context.Background() From ae0efe3cc5ab95294d085e166af1961ef44cf243 Mon Sep 17 00:00:00 2001 From: Jan Sternagel Date: Tue, 21 Oct 2025 09:15:05 +0200 Subject: [PATCH 46/52] Removed default flag value --- docs/stackit_beta_kms_key_create.md | 6 +++--- docs/stackit_beta_kms_wrapping-key_create.md | 6 +++--- internal/cmd/beta/kms/key/create/create.go | 10 +++------- internal/cmd/beta/kms/wrappingkey/create/create.go | 10 +++------- 4 files changed, 12 insertions(+), 20 deletions(-) diff --git a/docs/stackit_beta_kms_key_create.md b/docs/stackit_beta_kms_key_create.md index e7e59b6d9..d1ff0178f 100644 --- a/docs/stackit_beta_kms_key_create.md +++ b/docs/stackit_beta_kms_key_create.md @@ -23,14 +23,14 @@ stackit beta kms key create [flags] ### Options ``` - --algorithm string En-/Decryption / signing algorithm. Possible values: ["aes_256_gcm" "rsa_2048_oaep_sha256" "rsa_3072_oaep_sha256" "rsa_4096_oaep_sha256" "rsa_4096_oaep_sha512" "hmac_sha256" "hmac_sha384" "hmac_sha512" "ecdsa_p256_sha256" "ecdsa_p384_sha384" "ecdsa_p521_sha512"] (default "rsa_2048_oaep_sha256") + --algorithm string En-/Decryption / signing algorithm. Possible values: ["aes_256_gcm" "rsa_2048_oaep_sha256" "rsa_3072_oaep_sha256" "rsa_4096_oaep_sha256" "rsa_4096_oaep_sha512" "hmac_sha256" "hmac_sha384" "hmac_sha512" "ecdsa_p256_sha256" "ecdsa_p384_sha384" "ecdsa_p521_sha512"] --description string Optional description of the key -h, --help Help for "stackit beta kms key create" --import-only States whether versions can be created or only imported --keyring-id string ID of the KMS key ring --name string The display name to distinguish multiple keys - --protection string The underlying system that is responsible for protecting the key material. Possible values: ["symmetric_encrypt_decrypt" "asymmetric_encrypt_decrypt" "message_authentication_code" "asymmetric_sign_verify"] (default "software") - --purpose string Purpose of the key. Possible values: ["symmetric_encrypt_decrypt" "asymmetric_encrypt_decrypt" "message_authentication_code" "asymmetric_sign_verify"] (default "asymmetric_encrypt_decrypt") + --protection string The underlying system that is responsible for protecting the key material. Possible values: ["symmetric_encrypt_decrypt" "asymmetric_encrypt_decrypt" "message_authentication_code" "asymmetric_sign_verify"] + --purpose string Purpose of the key. Possible values: ["symmetric_encrypt_decrypt" "asymmetric_encrypt_decrypt" "message_authentication_code" "asymmetric_sign_verify"] ``` ### Options inherited from parent commands diff --git a/docs/stackit_beta_kms_wrapping-key_create.md b/docs/stackit_beta_kms_wrapping-key_create.md index e6b7697fb..ce6da97e3 100644 --- a/docs/stackit_beta_kms_wrapping-key_create.md +++ b/docs/stackit_beta_kms_wrapping-key_create.md @@ -23,13 +23,13 @@ stackit beta kms wrapping-key create [flags] ### Options ``` - --algorithm string En-/Decryption / signing algorithm. Possible values: ["rsa_2048_oaep_sha256" "rsa_3072_oaep_sha256" "rsa_4096_oaep_sha256" "rsa_4096_oaep_sha512" "rsa_2048_oaep_sha256_aes_256_key_wrap" "rsa_3072_oaep_sha256_aes_256_key_wrap" "rsa_4096_oaep_sha256_aes_256_key_wrap" "rsa_4096_oaep_sha512_aes_256_key_wrap"] (default "rsa_2048_oaep_sha256") + --algorithm string En-/Decryption / signing algorithm. Possible values: ["rsa_2048_oaep_sha256" "rsa_3072_oaep_sha256" "rsa_4096_oaep_sha256" "rsa_4096_oaep_sha512" "rsa_2048_oaep_sha256_aes_256_key_wrap" "rsa_3072_oaep_sha256_aes_256_key_wrap" "rsa_4096_oaep_sha256_aes_256_key_wrap" "rsa_4096_oaep_sha512_aes_256_key_wrap"] --description string Optional description of the wrapping key -h, --help Help for "stackit beta kms wrapping-key create" --keyring-id string ID of the KMS key ring --name string The display name to distinguish multiple wrapping keys - --protection string The underlying system that is responsible for protecting the wrapping key material. Possible values: ["wrap_symmetric_key" "wrap_asymmetric_key"] (default "software") - --purpose string Purpose of the wrapping key. Possible values: ["wrap_symmetric_key" "wrap_asymmetric_key"] (default "wrap_asymmetric_key") + --protection string The underlying system that is responsible for protecting the wrapping key material. Possible values: ["wrap_symmetric_key" "wrap_asymmetric_key"] + --purpose string Purpose of the wrapping key. Possible values: ["wrap_symmetric_key" "wrap_asymmetric_key"] ``` ### Options inherited from parent commands diff --git a/internal/cmd/beta/kms/key/create/create.go b/internal/cmd/beta/kms/key/create/create.go index 1443dba6a..5a60b4606 100644 --- a/internal/cmd/beta/kms/key/create/create.go +++ b/internal/cmd/beta/kms/key/create/create.go @@ -31,10 +31,6 @@ const ( importOnlyFlag = "import-only" purposeFlag = "purpose" protectionFlag = "protection" - - defaultAlgorithm = kms.ALGORITHM_RSA_2048_OAEP_SHA256 - defaultPurpose = kms.PURPOSE_ASYMMETRIC_ENCRYPT_DECRYPT - defaultProtection = kms.PROTECTION_SOFTWARE ) type inputModel struct { @@ -183,21 +179,21 @@ func configureFlags(cmd *cobra.Command) { for _, val := range kms.AllowedAlgorithmEnumValues { algorithmFlagOptions = append(algorithmFlagOptions, string(val)) } - cmd.Flags().Var(flags.EnumFlag(false, string(defaultAlgorithm), algorithmFlagOptions...), algorithmFlag, fmt.Sprintf("En-/Decryption / signing algorithm. Possible values: %q", algorithmFlagOptions)) + cmd.Flags().Var(flags.EnumFlag(false, "", algorithmFlagOptions...), algorithmFlag, fmt.Sprintf("En-/Decryption / signing algorithm. Possible values: %q", algorithmFlagOptions)) // Purpose var purposeFlagOptions []string for _, val := range kms.AllowedPurposeEnumValues { purposeFlagOptions = append(purposeFlagOptions, string(val)) } - cmd.Flags().Var(flags.EnumFlag(false, string(defaultPurpose), purposeFlagOptions...), purposeFlag, fmt.Sprintf("Purpose of the key. Possible values: %q", purposeFlagOptions)) + cmd.Flags().Var(flags.EnumFlag(false, "", purposeFlagOptions...), purposeFlag, fmt.Sprintf("Purpose of the key. Possible values: %q", purposeFlagOptions)) // Protection var protectionFlagOptions []string for _, val := range kms.AllowedProtectionEnumValues { protectionFlagOptions = append(protectionFlagOptions, string(val)) } - cmd.Flags().Var(flags.EnumFlag(false, string(defaultProtection), protectionFlagOptions...), protectionFlag, fmt.Sprintf("The underlying system that is responsible for protecting the key material. Possible values: %q", purposeFlagOptions)) + cmd.Flags().Var(flags.EnumFlag(false, "", protectionFlagOptions...), protectionFlag, fmt.Sprintf("The underlying system that is responsible for protecting the key material. Possible values: %q", purposeFlagOptions)) // All further non Enum Flags cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS key ring") diff --git a/internal/cmd/beta/kms/wrappingkey/create/create.go b/internal/cmd/beta/kms/wrappingkey/create/create.go index db3884ae9..37ce79205 100644 --- a/internal/cmd/beta/kms/wrappingkey/create/create.go +++ b/internal/cmd/beta/kms/wrappingkey/create/create.go @@ -30,10 +30,6 @@ const ( displayNameFlag = "name" purposeFlag = "purpose" protectionFlag = "protection" - - defaultWrappingAlgorithm = kms.WRAPPINGALGORITHM__2048_OAEP_SHA256 - defaultWrappingPurpose = kms.WRAPPINGPURPOSE_ASYMMETRIC_KEY - defaultProtection = kms.PROTECTION_SOFTWARE ) type inputModel struct { @@ -181,14 +177,14 @@ func configureFlags(cmd *cobra.Command) { for _, val := range kms.AllowedWrappingAlgorithmEnumValues { algorithmFlagOptions = append(algorithmFlagOptions, string(val)) } - cmd.Flags().Var(flags.EnumFlag(false, string(defaultWrappingAlgorithm), algorithmFlagOptions...), algorithmFlag, fmt.Sprintf("En-/Decryption / signing algorithm. Possible values: %q", algorithmFlagOptions)) + cmd.Flags().Var(flags.EnumFlag(false, "", algorithmFlagOptions...), algorithmFlag, fmt.Sprintf("En-/Decryption / signing algorithm. Possible values: %q", algorithmFlagOptions)) // Purpose var purposeFlagOptions []string for _, val := range kms.AllowedWrappingPurposeEnumValues { purposeFlagOptions = append(purposeFlagOptions, string(val)) } - cmd.Flags().Var(flags.EnumFlag(false, string(defaultWrappingPurpose), purposeFlagOptions...), purposeFlag, fmt.Sprintf("Purpose of the wrapping key. Possible values: %q", purposeFlagOptions)) + cmd.Flags().Var(flags.EnumFlag(false, "", purposeFlagOptions...), purposeFlag, fmt.Sprintf("Purpose of the wrapping key. Possible values: %q", purposeFlagOptions)) // Protection // backend was deprectaed in /v1beta, but protection is a required attribute with value "software" @@ -196,7 +192,7 @@ func configureFlags(cmd *cobra.Command) { for _, val := range kms.AllowedProtectionEnumValues { protectionFlagOptions = append(protectionFlagOptions, string(val)) } - cmd.Flags().Var(flags.EnumFlag(false, string(defaultProtection), protectionFlagOptions...), protectionFlag, fmt.Sprintf("The underlying system that is responsible for protecting the wrapping key material. Possible values: %q", purposeFlagOptions)) + cmd.Flags().Var(flags.EnumFlag(false, "", protectionFlagOptions...), protectionFlag, fmt.Sprintf("The underlying system that is responsible for protecting the wrapping key material. Possible values: %q", purposeFlagOptions)) // All further non Enum Flags cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS key ring") From eae8ec265663690d9b945367ccd5408dc069ea96 Mon Sep 17 00:00:00 2001 From: Jan Sternagel Date: Tue, 21 Oct 2025 11:19:56 +0200 Subject: [PATCH 47/52] added import from file --- docs/stackit_beta_kms_key_import.md | 11 +++++++---- internal/cmd/beta/kms/key/importKey/importKey.go | 15 ++++++++++----- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/docs/stackit_beta_kms_key_import.md b/docs/stackit_beta_kms_key_import.md index 7a683d6a7..284b66c33 100644 --- a/docs/stackit_beta_kms_key_import.md +++ b/docs/stackit_beta_kms_key_import.md @@ -4,7 +4,7 @@ Import a KMS key ### Synopsis -Import a new version to the given KMS key. +After encrypting the secret with the wrapping key’s public key and Base64-encoding it, import it as a new version of the specified KMS key. ``` stackit beta kms key import KEY_ID [flags] @@ -13,8 +13,11 @@ stackit beta kms key import KEY_ID [flags] ### Examples ``` - Import a new version for the given KMS key "MY_KEY_ID" - $ stackit beta kms key import "MY_KEY_ID" --keyring-id "MY_KEYRING_ID" --wrapped-key "base64-encoded-wrapped-key-material" --wrapping-key-id "MY_WRAPPING_KEY_ID" + Import a new version for the given KMS key "MY_KEY_ID" from literal value + $ stackit beta kms key import "MY_KEY_ID" --keyring-id "MY_KEYRING_ID" --wrapped-key "BASE64_VALUE" --wrapping-key-id "MY_WRAPPING_KEY_ID" + + Import from a file + $ stackit beta kms key import "MY_KEY_ID" --keyring-id "MY_KEYRING_ID" --wrapped-key "path/to/wrapped.key.b64" --wrapping-key-id "MY_WRAPPING_KEY_ID" ``` ### Options @@ -22,7 +25,7 @@ stackit beta kms key import KEY_ID [flags] ``` -h, --help Help for "stackit beta kms key import" --keyring-id string ID of the KMS key ring - --wrapped-key string The wrapped key material that has to be imported. Encoded in base64 + --wrapped-key string The wrapped key material to be imported. Base64-encoded. Pass the value directly or a file path (e.g. path/to/wrapped.key.b64) --wrapping-key-id string The unique id of the wrapping key the key material has been wrapped with ``` diff --git a/internal/cmd/beta/kms/key/importKey/importKey.go b/internal/cmd/beta/kms/key/importKey/importKey.go index 06f26c807..b871eca0c 100644 --- a/internal/cmd/beta/kms/key/importKey/importKey.go +++ b/internal/cmd/beta/kms/key/importKey/importKey.go @@ -42,13 +42,18 @@ func NewCmd(params *params.CmdParams) *cobra.Command { cmd := &cobra.Command{ Use: fmt.Sprintf("import %s", keyIdArg), Short: "Import a KMS key", - Long: "Import a new version to the given KMS key.", + Long: "After encrypting the secret with the wrapping key’s public key and Base64-encoding it, import it as a new version of the specified KMS key.", Args: args.SingleArg(keyIdArg, utils.ValidateUUID), Example: examples.Build( examples.NewExample( - `Import a new version for the given KMS key "MY_KEY_ID"`, - `$ stackit beta kms key import "MY_KEY_ID" --keyring-id "MY_KEYRING_ID" --wrapped-key "base64-encoded-wrapped-key-material" --wrapping-key-id "MY_WRAPPING_KEY_ID"`), + `Import a new version for the given KMS key "MY_KEY_ID" from literal value`, + `$ stackit beta kms key import "MY_KEY_ID" --keyring-id "MY_KEYRING_ID" --wrapped-key "BASE64_VALUE" --wrapping-key-id "MY_WRAPPING_KEY_ID"`), + examples.NewExample( + `Import from a file`, + `$ stackit beta kms key import "MY_KEY_ID" --keyring-id "MY_KEYRING_ID" --wrapped-key "path/to/wrapped.key.b64" --wrapping-key-id "MY_WRAPPING_KEY_ID"`, + ), ), + RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() model, err := parseInput(params.Printer, cmd, args) @@ -109,7 +114,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu if err != nil || *wrappedKey == "" { return nil, &cliErr.FlagValidationError{ Flag: wrappedKeyFlag, - Details: "The 'wrappedKey' argument is required and needs to be base64 encoded.", + Details: "The 'wrappedKey' argument is required and needs to be base64 encoded (whether provided inline or via file).", } } @@ -168,7 +173,7 @@ func outputResult(p *print.Printer, outputFormat, keyRingName, keyName string, r func configureFlags(cmd *cobra.Command) { cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS key ring") - cmd.Flags().String(wrappedKeyFlag, "", "The wrapped key material that has to be imported. Encoded in base64") + cmd.Flags().Var(flags.ReadFromFileFlag(), wrappedKeyFlag, "The wrapped key material to be imported. Base64-encoded. Pass the value directly or a file path (e.g. path/to/wrapped.key.b64)") cmd.Flags().Var(flags.UUIDFlag(), wrappingKeyIdFlag, "The unique id of the wrapping key the key material has been wrapped with") err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, wrappedKeyFlag, wrappingKeyIdFlag) From 5869606df3e00cbea1b88882739733bd8e744fa1 Mon Sep 17 00:00:00 2001 From: Jan Sternagel Date: Tue, 21 Oct 2025 11:50:51 +0200 Subject: [PATCH 48/52] better examples --- docs/stackit_beta_kms_key_create.md | 20 +++++++++++++++---- docs/stackit_beta_kms_keyring_create.md | 5 ++++- docs/stackit_beta_kms_wrapping-key_create.md | 8 ++++---- internal/cmd/beta/kms/key/create/create.go | 20 +++++++++++++++---- .../cmd/beta/kms/keyring/create/create.go | 5 ++++- .../cmd/beta/kms/wrappingkey/create/create.go | 8 ++++---- 6 files changed, 48 insertions(+), 18 deletions(-) diff --git a/docs/stackit_beta_kms_key_create.md b/docs/stackit_beta_kms_key_create.md index d1ff0178f..10fbac43f 100644 --- a/docs/stackit_beta_kms_key_create.md +++ b/docs/stackit_beta_kms_key_create.md @@ -13,11 +13,23 @@ stackit beta kms key create [flags] ### Examples ``` - Create a Symmetric KMS key - $ stackit beta kms key create --keyring-id "MY_KEYRING_ID" --algorithm "rsa_2048_oaep_sha256" --name "my-key-name" --purpose "asymmetric_encrypt_decrypt" --protection "software" + Create a symmetric AES key (AES-256) with the name "symm-aes-gcm" under the key ring "MY_KEYRING_ID" + $ stackit beta kms key create --keyring-id "MY_KEYRING_ID" --algorithm "aes_256_gcm" --name "symm-aes-gcm" --purpose "symmetric_encrypt_decrypt" --protection "software" - Create a Message Authentication KMS key - $ stackit beta kms key create --keyring-id "MY_KEYRING_ID" --algorithm "hmac_sha512" --name "my-key-name" --purpose "message_authentication_code" --protection "software" + Create an asymmetric RSA encryption key (RSA-2048) + $ stackit beta kms key create --keyring-id "MY_KEYRING_ID" --algorithm "rsa_2048_oaep_sha256" --name "prod-orders-rsa" --purpose "asymmetric_encrypt_decrypt" --protection "software" + + Create a message authentication key (HMAC-SHA512) + $ stackit beta kms key create --keyring-id "MY_KEYRING_ID" --algorithm "hmac_sha512" --name "api-mac-key" --purpose "message_authentication_code" --protection "software" + + Create an ECDSA P-256 key for signing & verification + $ stackit beta kms key create --keyring-id "MY_KEYRING_ID" --algorithm "ecdsa_p256_sha256" --name "signing-ecdsa-p256" --purpose "asymmetric_sign_verify" --protection "software" + + Create an import-only key (versions must be imported) + $ stackit beta kms key create --keyring-id "MY_KEYRING_ID" --algorithm "rsa_2048_oaep_sha256" --name "ext-managed-rsa" --purpose "asymmetric_encrypt_decrypt" --protection "software" --import-only + + Create a key and print the result as YAML + $ stackit beta kms key create --keyring-id "MY_KEYRING_ID" --algorithm "rsa_2048_oaep_sha256" --name "yaml-output-rsa" --purpose "asymmetric_encrypt_decrypt" --protection "software" --output yaml ``` ### Options diff --git a/docs/stackit_beta_kms_keyring_create.md b/docs/stackit_beta_kms_keyring_create.md index bd1565d3d..d02e6e13e 100644 --- a/docs/stackit_beta_kms_keyring_create.md +++ b/docs/stackit_beta_kms_keyring_create.md @@ -13,11 +13,14 @@ stackit beta kms keyring create [flags] ### Examples ``` - Create a KMS key ring + Create a KMS key ring with name "my-keyring" $ stackit beta kms keyring create --name my-keyring Create a KMS key ring with a description $ stackit beta kms keyring create --name my-keyring --description my-description + + Create a KMS key ring and print the result as YAML + $ stackit beta kms keyring create --name my-keyring -o yaml ``` ### Options diff --git a/docs/stackit_beta_kms_wrapping-key_create.md b/docs/stackit_beta_kms_wrapping-key_create.md index ce6da97e3..57e41a81a 100644 --- a/docs/stackit_beta_kms_wrapping-key_create.md +++ b/docs/stackit_beta_kms_wrapping-key_create.md @@ -13,11 +13,11 @@ stackit beta kms wrapping-key create [flags] ### Examples ``` - Create a Symmetric KMS wrapping key - $ stackit beta kms wrapping-key create --keyring-id "MY_KEYRING_ID" --algorithm "rsa_2048_oaep_sha256" --name "my-wrapping-key-name" --purpose "wrap_asymmetric_key" --protection "software" + Create a symmetric (RSA + AES) KMS wrapping key with name "my-wrapping-key-name" in keyring with ID "MY_KEYRING_ID" + $ stackit beta kms wrapping-key create --keyring-id "MY_KEYRING_ID" --algorithm "rsa_2048_oaep_sha256_aes_256_key_wrap" --name "my-wrapping-key-name" --purpose "wrap_symmetric_key" --protection "software" - Create an Asymmetric KMS wrapping key with a description - $ stackit beta kms wrapping-key create --keyring-id "MY_KEYRING_ID" --algorithm "hmac_sha256" --name "my-wrapping-key-name" --description "my-description" --purpose "wrap_asymmetric_key" --protection "software" + Create an asymmetric (RSA) KMS wrapping key with name "my-wrapping-key-name" in keyring with ID "MY_KEYRING_ID" + $ stackit beta kms wrapping-key create --keyring-id "MY_KEYRING_ID" --algorithm "rsa_3072_oaep_sha256" --name "my-wrapping-key-name" --purpose "wrap_asymmetric_key" --protection "software" ``` ### Options diff --git a/internal/cmd/beta/kms/key/create/create.go b/internal/cmd/beta/kms/key/create/create.go index 5a60b4606..a3e1f8eea 100644 --- a/internal/cmd/beta/kms/key/create/create.go +++ b/internal/cmd/beta/kms/key/create/create.go @@ -53,11 +53,23 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Args: args.NoArgs, Example: examples.Build( examples.NewExample( - `Create a Symmetric KMS key`, - `$ stackit beta kms key create --keyring-id "MY_KEYRING_ID" --algorithm "rsa_2048_oaep_sha256" --name "my-key-name" --purpose "asymmetric_encrypt_decrypt" --protection "software"`), + `Create a symmetric AES key (AES-256) with the name "symm-aes-gcm" under the key ring "MY_KEYRING_ID"`, + `$ stackit beta kms key create --keyring-id "MY_KEYRING_ID" --algorithm "aes_256_gcm" --name "symm-aes-gcm" --purpose "symmetric_encrypt_decrypt" --protection "software"`), examples.NewExample( - `Create a Message Authentication KMS key`, - `$ stackit beta kms key create --keyring-id "MY_KEYRING_ID" --algorithm "hmac_sha512" --name "my-key-name" --purpose "message_authentication_code" --protection "software"`), + `Create an asymmetric RSA encryption key (RSA-2048)`, + `$ stackit beta kms key create --keyring-id "MY_KEYRING_ID" --algorithm "rsa_2048_oaep_sha256" --name "prod-orders-rsa" --purpose "asymmetric_encrypt_decrypt" --protection "software"`), + examples.NewExample( + `Create a message authentication key (HMAC-SHA512)`, + `$ stackit beta kms key create --keyring-id "MY_KEYRING_ID" --algorithm "hmac_sha512" --name "api-mac-key" --purpose "message_authentication_code" --protection "software"`), + examples.NewExample( + `Create an ECDSA P-256 key for signing & verification`, + `$ stackit beta kms key create --keyring-id "MY_KEYRING_ID" --algorithm "ecdsa_p256_sha256" --name "signing-ecdsa-p256" --purpose "asymmetric_sign_verify" --protection "software"`), + examples.NewExample( + `Create an import-only key (versions must be imported)`, + `$ stackit beta kms key create --keyring-id "MY_KEYRING_ID" --algorithm "rsa_2048_oaep_sha256" --name "ext-managed-rsa" --purpose "asymmetric_encrypt_decrypt" --protection "software" --import-only`), + examples.NewExample( + `Create a key and print the result as YAML`, + `$ stackit beta kms key create --keyring-id "MY_KEYRING_ID" --algorithm "rsa_2048_oaep_sha256" --name "yaml-output-rsa" --purpose "asymmetric_encrypt_decrypt" --protection "software" --output yaml`), ), RunE: func(cmd *cobra.Command, _ []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/keyring/create/create.go b/internal/cmd/beta/kms/keyring/create/create.go index 71bab26a8..b4103e957 100644 --- a/internal/cmd/beta/kms/keyring/create/create.go +++ b/internal/cmd/beta/kms/keyring/create/create.go @@ -41,11 +41,14 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Args: args.NoArgs, Example: examples.Build( examples.NewExample( - `Create a KMS key ring`, + `Create a KMS key ring with name "my-keyring"`, "$ stackit beta kms keyring create --name my-keyring"), examples.NewExample( `Create a KMS key ring with a description`, "$ stackit beta kms keyring create --name my-keyring --description my-description"), + examples.NewExample( + `Create a KMS key ring and print the result as YAML`, + "$ stackit beta kms keyring create --name my-keyring -o yaml"), ), RunE: func(cmd *cobra.Command, _ []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/wrappingkey/create/create.go b/internal/cmd/beta/kms/wrappingkey/create/create.go index 37ce79205..ea94d4b9e 100644 --- a/internal/cmd/beta/kms/wrappingkey/create/create.go +++ b/internal/cmd/beta/kms/wrappingkey/create/create.go @@ -51,11 +51,11 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Args: args.NoArgs, Example: examples.Build( examples.NewExample( - `Create a Symmetric KMS wrapping key`, - `$ stackit beta kms wrapping-key create --keyring-id "MY_KEYRING_ID" --algorithm "rsa_2048_oaep_sha256" --name "my-wrapping-key-name" --purpose "wrap_asymmetric_key" --protection "software"`), + `Create a symmetric (RSA + AES) KMS wrapping key with name "my-wrapping-key-name" in keyring with ID "MY_KEYRING_ID"`, + `$ stackit beta kms wrapping-key create --keyring-id "MY_KEYRING_ID" --algorithm "rsa_2048_oaep_sha256_aes_256_key_wrap" --name "my-wrapping-key-name" --purpose "wrap_symmetric_key" --protection "software"`), examples.NewExample( - `Create an Asymmetric KMS wrapping key with a description`, - `$ stackit beta kms wrapping-key create --keyring-id "MY_KEYRING_ID" --algorithm "hmac_sha256" --name "my-wrapping-key-name" --description "my-description" --purpose "wrap_asymmetric_key" --protection "software"`), + `Create an asymmetric (RSA) KMS wrapping key with name "my-wrapping-key-name" in keyring with ID "MY_KEYRING_ID"`, + `$ stackit beta kms wrapping-key create --keyring-id "MY_KEYRING_ID" --algorithm "rsa_3072_oaep_sha256" --name "my-wrapping-key-name" --purpose "wrap_asymmetric_key" --protection "software"`), ), RunE: func(cmd *cobra.Command, _ []string) error { ctx := context.Background() From 53845d348fefc9f13631df5f2a65a33cb6aab87f Mon Sep 17 00:00:00 2001 From: Jan Sternagel Date: Tue, 21 Oct 2025 11:58:46 +0200 Subject: [PATCH 49/52] fix the path --- docs/stackit_beta_kms_key_import.md | 4 ++-- internal/cmd/beta/kms/key/importKey/importKey.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/stackit_beta_kms_key_import.md b/docs/stackit_beta_kms_key_import.md index 284b66c33..fe4af56d5 100644 --- a/docs/stackit_beta_kms_key_import.md +++ b/docs/stackit_beta_kms_key_import.md @@ -17,7 +17,7 @@ stackit beta kms key import KEY_ID [flags] $ stackit beta kms key import "MY_KEY_ID" --keyring-id "MY_KEYRING_ID" --wrapped-key "BASE64_VALUE" --wrapping-key-id "MY_WRAPPING_KEY_ID" Import from a file - $ stackit beta kms key import "MY_KEY_ID" --keyring-id "MY_KEYRING_ID" --wrapped-key "path/to/wrapped.key.b64" --wrapping-key-id "MY_WRAPPING_KEY_ID" + $ stackit beta kms key import "MY_KEY_ID" --keyring-id "MY_KEYRING_ID" --wrapped-key "@path/to/wrapped.key.b64" --wrapping-key-id "MY_WRAPPING_KEY_ID" ``` ### Options @@ -25,7 +25,7 @@ stackit beta kms key import KEY_ID [flags] ``` -h, --help Help for "stackit beta kms key import" --keyring-id string ID of the KMS key ring - --wrapped-key string The wrapped key material to be imported. Base64-encoded. Pass the value directly or a file path (e.g. path/to/wrapped.key.b64) + --wrapped-key string The wrapped key material to be imported. Base64-encoded. Pass the value directly or a file path (e.g. @path/to/wrapped.key.b64) --wrapping-key-id string The unique id of the wrapping key the key material has been wrapped with ``` diff --git a/internal/cmd/beta/kms/key/importKey/importKey.go b/internal/cmd/beta/kms/key/importKey/importKey.go index b871eca0c..c8cf7d7ed 100644 --- a/internal/cmd/beta/kms/key/importKey/importKey.go +++ b/internal/cmd/beta/kms/key/importKey/importKey.go @@ -50,7 +50,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { `$ stackit beta kms key import "MY_KEY_ID" --keyring-id "MY_KEYRING_ID" --wrapped-key "BASE64_VALUE" --wrapping-key-id "MY_WRAPPING_KEY_ID"`), examples.NewExample( `Import from a file`, - `$ stackit beta kms key import "MY_KEY_ID" --keyring-id "MY_KEYRING_ID" --wrapped-key "path/to/wrapped.key.b64" --wrapping-key-id "MY_WRAPPING_KEY_ID"`, + `$ stackit beta kms key import "MY_KEY_ID" --keyring-id "MY_KEYRING_ID" --wrapped-key "@path/to/wrapped.key.b64" --wrapping-key-id "MY_WRAPPING_KEY_ID"`, ), ), @@ -173,7 +173,7 @@ func outputResult(p *print.Printer, outputFormat, keyRingName, keyName string, r func configureFlags(cmd *cobra.Command) { cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS key ring") - cmd.Flags().Var(flags.ReadFromFileFlag(), wrappedKeyFlag, "The wrapped key material to be imported. Base64-encoded. Pass the value directly or a file path (e.g. path/to/wrapped.key.b64)") + cmd.Flags().Var(flags.ReadFromFileFlag(), wrappedKeyFlag, "The wrapped key material to be imported. Base64-encoded. Pass the value directly or a file path (e.g. @path/to/wrapped.key.b64)") cmd.Flags().Var(flags.UUIDFlag(), wrappingKeyIdFlag, "The unique id of the wrapping key the key material has been wrapped with") err := flags.MarkFlagsRequired(cmd, keyRingIdFlag, wrappedKeyFlag, wrappingKeyIdFlag) From de6aba725e62cd653e3ad57a86064ceebe099f67 Mon Sep 17 00:00:00 2001 From: Jan Sternagel Date: Tue, 21 Oct 2025 12:10:00 +0200 Subject: [PATCH 50/52] Fix more spelling mistakes --- docs/stackit_beta_kms_key_delete.md | 2 +- docs/stackit_beta_kms_key_list.md | 2 +- docs/stackit_beta_kms_key_restore.md | 6 +++--- docs/stackit_beta_kms_key_rotate.md | 4 ++-- docs/stackit_beta_kms_version_restore.md | 2 +- docs/stackit_beta_kms_wrapping-key_create.md | 4 ++-- docs/stackit_beta_kms_wrapping-key_list.md | 4 ++-- internal/cmd/beta/kms/key/delete/delete.go | 2 +- internal/cmd/beta/kms/key/list/list.go | 2 +- internal/cmd/beta/kms/key/restore/restore.go | 6 +++--- internal/cmd/beta/kms/key/rotate/rotate.go | 4 ++-- internal/cmd/beta/kms/version/destroy/destroy.go | 2 +- internal/cmd/beta/kms/version/disable/disable.go | 2 +- internal/cmd/beta/kms/version/enable/enable.go | 2 +- internal/cmd/beta/kms/version/restore/restore.go | 4 ++-- internal/cmd/beta/kms/wrappingkey/create/create.go | 4 ++-- internal/cmd/beta/kms/wrappingkey/list/list.go | 4 ++-- internal/pkg/services/kms/utils/utils.go | 2 +- 18 files changed, 29 insertions(+), 29 deletions(-) diff --git a/docs/stackit_beta_kms_key_delete.md b/docs/stackit_beta_kms_key_delete.md index 86117ce48..55f7cd1d7 100644 --- a/docs/stackit_beta_kms_key_delete.md +++ b/docs/stackit_beta_kms_key_delete.md @@ -21,7 +21,7 @@ stackit beta kms key delete KEY_ID [flags] ``` -h, --help Help for "stackit beta kms key delete" - --keyring-id string ID of the KMS Key Ring where the Key is stored + --keyring-id string ID of the KMS key ring where the key is stored ``` ### Options inherited from parent commands diff --git a/docs/stackit_beta_kms_key_list.md b/docs/stackit_beta_kms_key_list.md index 0cf81b773..3feb8c189 100644 --- a/docs/stackit_beta_kms_key_list.md +++ b/docs/stackit_beta_kms_key_list.md @@ -24,7 +24,7 @@ stackit beta kms key list [flags] ``` -h, --help Help for "stackit beta kms key list" - --keyring-id string ID of the KMS Key Ring where the Key is stored + --keyring-id string ID of the KMS key ring where the key is stored ``` ### Options inherited from parent commands diff --git a/docs/stackit_beta_kms_key_restore.md b/docs/stackit_beta_kms_key_restore.md index e03d236b1..689248fe2 100644 --- a/docs/stackit_beta_kms_key_restore.md +++ b/docs/stackit_beta_kms_key_restore.md @@ -4,7 +4,7 @@ Restore a key ### Synopsis -Restores the given key from being deleted. +Restores the given key from deletion. ``` stackit beta kms key restore KEY_ID [flags] @@ -14,14 +14,14 @@ stackit beta kms key restore KEY_ID [flags] ``` Restore a KMS key "MY_KEY_ID" inside the key ring "MY_KEYRING_ID" that was scheduled for deletion. - $ stackit beta kms keyring restore "MY_KEY_ID" --keyring-id "MY_KEYRING_ID" + $ stackit beta kms key restore "MY_KEY_ID" --keyring-id "MY_KEYRING_ID" ``` ### Options ``` -h, --help Help for "stackit beta kms key restore" - --keyring-id string ID of the KMS Key Ring where the Key is stored + --keyring-id string ID of the KMS key ring where the key is stored ``` ### Options inherited from parent commands diff --git a/docs/stackit_beta_kms_key_rotate.md b/docs/stackit_beta_kms_key_rotate.md index 4f4d7029e..e6cc22630 100644 --- a/docs/stackit_beta_kms_key_rotate.md +++ b/docs/stackit_beta_kms_key_rotate.md @@ -13,7 +13,7 @@ stackit beta kms key rotate KEY_ID [flags] ### Examples ``` - Rotate a KMS key "MY_KEY_ID" and increase it's version inside the key ring "MY_KEYRING_ID". + Rotate a KMS key "MY_KEY_ID" and increase its version inside the key ring "MY_KEYRING_ID". $ stackit beta kms key rotate "MY_KEY_ID" --keyring-id "MY_KEYRING_ID" ``` @@ -21,7 +21,7 @@ stackit beta kms key rotate KEY_ID [flags] ``` -h, --help Help for "stackit beta kms key rotate" - --keyring-id string ID of the KMS key Ring where the key is stored + --keyring-id string ID of the KMS key ring where the key is stored ``` ### Options inherited from parent commands diff --git a/docs/stackit_beta_kms_version_restore.md b/docs/stackit_beta_kms_version_restore.md index ae3dd4a73..303774724 100644 --- a/docs/stackit_beta_kms_version_restore.md +++ b/docs/stackit_beta_kms_version_restore.md @@ -4,7 +4,7 @@ Restore a key version ### Synopsis -Restores the specified version of key. +Restores the specified version of a key. ``` stackit beta kms version restore VERSION_NUMBER [flags] diff --git a/docs/stackit_beta_kms_wrapping-key_create.md b/docs/stackit_beta_kms_wrapping-key_create.md index 57e41a81a..8c6a78a1a 100644 --- a/docs/stackit_beta_kms_wrapping-key_create.md +++ b/docs/stackit_beta_kms_wrapping-key_create.md @@ -13,10 +13,10 @@ stackit beta kms wrapping-key create [flags] ### Examples ``` - Create a symmetric (RSA + AES) KMS wrapping key with name "my-wrapping-key-name" in keyring with ID "MY_KEYRING_ID" + Create a symmetric (RSA + AES) KMS wrapping key with name "my-wrapping-key-name" in key ring with ID "MY_KEYRING_ID" $ stackit beta kms wrapping-key create --keyring-id "MY_KEYRING_ID" --algorithm "rsa_2048_oaep_sha256_aes_256_key_wrap" --name "my-wrapping-key-name" --purpose "wrap_symmetric_key" --protection "software" - Create an asymmetric (RSA) KMS wrapping key with name "my-wrapping-key-name" in keyring with ID "MY_KEYRING_ID" + Create an asymmetric (RSA) KMS wrapping key with name "my-wrapping-key-name" in key ring with ID "MY_KEYRING_ID" $ stackit beta kms wrapping-key create --keyring-id "MY_KEYRING_ID" --algorithm "rsa_3072_oaep_sha256" --name "my-wrapping-key-name" --purpose "wrap_asymmetric_key" --protection "software" ``` diff --git a/docs/stackit_beta_kms_wrapping-key_list.md b/docs/stackit_beta_kms_wrapping-key_list.md index ca93dcae2..89cf7f99f 100644 --- a/docs/stackit_beta_kms_wrapping-key_list.md +++ b/docs/stackit_beta_kms_wrapping-key_list.md @@ -17,14 +17,14 @@ stackit beta kms wrapping-key list [flags] $ stackit beta kms wrapping-key list --keyring-id "MY_KEYRING_ID" List all KMS wrapping keys in JSON format - $ stackit beta kms wrappingkeys list --keyring-id "MY_KEYRING_ID" --output-format json + $ stackit beta kms wrapping-key list --keyring-id "MY_KEYRING_ID" --output-format json ``` ### Options ``` -h, --help Help for "stackit beta kms wrapping-key list" - --keyring-id string ID of the KMS Key Ring where the Key is stored + --keyring-id string ID of the KMS key ring where the key is stored ``` ### Options inherited from parent commands diff --git a/internal/cmd/beta/kms/key/delete/delete.go b/internal/cmd/beta/kms/key/delete/delete.go index 0f7915212..487b315c9 100644 --- a/internal/cmd/beta/kms/key/delete/delete.go +++ b/internal/cmd/beta/kms/key/delete/delete.go @@ -117,7 +117,7 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClie } func configureFlags(cmd *cobra.Command) { - cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS Key Ring where the Key is stored") + cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS key ring where the key is stored") err := flags.MarkFlagsRequired(cmd, keyRingIdFlag) cobra.CheckErr(err) diff --git a/internal/cmd/beta/kms/key/list/list.go b/internal/cmd/beta/kms/key/list/list.go index 4bc78e29a..43d3dd62c 100644 --- a/internal/cmd/beta/kms/key/list/list.go +++ b/internal/cmd/beta/kms/key/list/list.go @@ -92,7 +92,7 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClie } func configureFlags(cmd *cobra.Command) { - cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS Key Ring where the Key is stored") + cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS key ring where the key is stored") err := flags.MarkFlagsRequired(cmd, keyRingIdFlag) cobra.CheckErr(err) diff --git a/internal/cmd/beta/kms/key/restore/restore.go b/internal/cmd/beta/kms/key/restore/restore.go index 519c2ebd4..0dd240a65 100644 --- a/internal/cmd/beta/kms/key/restore/restore.go +++ b/internal/cmd/beta/kms/key/restore/restore.go @@ -37,12 +37,12 @@ func NewCmd(params *params.CmdParams) *cobra.Command { cmd := &cobra.Command{ Use: fmt.Sprintf("restore %s", keyIdArg), Short: "Restore a key", - Long: "Restores the given key from being deleted.", + Long: "Restores the given key from deletion.", Args: args.SingleArg(keyIdArg, utils.ValidateUUID), Example: examples.Build( examples.NewExample( `Restore a KMS key "MY_KEY_ID" inside the key ring "MY_KEYRING_ID" that was scheduled for deletion.`, - `$ stackit beta kms keyring restore "MY_KEY_ID" --keyring-id "MY_KEYRING_ID"`), + `$ stackit beta kms key restore "MY_KEY_ID" --keyring-id "MY_KEYRING_ID"`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() @@ -116,7 +116,7 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClie } func configureFlags(cmd *cobra.Command) { - cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS Key Ring where the Key is stored") + cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS key ring where the key is stored") err := flags.MarkFlagsRequired(cmd, keyRingIdFlag) cobra.CheckErr(err) diff --git a/internal/cmd/beta/kms/key/rotate/rotate.go b/internal/cmd/beta/kms/key/rotate/rotate.go index 0579c4940..e0523d2fc 100644 --- a/internal/cmd/beta/kms/key/rotate/rotate.go +++ b/internal/cmd/beta/kms/key/rotate/rotate.go @@ -41,7 +41,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Args: args.SingleArg(keyIdArg, utils.ValidateUUID), Example: examples.Build( examples.NewExample( - `Rotate a KMS key "MY_KEY_ID" and increase it's version inside the key ring "MY_KEYRING_ID".`, + `Rotate a KMS key "MY_KEY_ID" and increase its version inside the key ring "MY_KEYRING_ID".`, `$ stackit beta kms key rotate "MY_KEY_ID" --keyring-id "MY_KEYRING_ID"`), ), RunE: func(cmd *cobra.Command, args []string) error { @@ -110,7 +110,7 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClie } func configureFlags(cmd *cobra.Command) { - cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS key Ring where the key is stored") + cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS key ring where the key is stored") err := flags.MarkFlagsRequired(cmd, keyRingIdFlag) cobra.CheckErr(err) diff --git a/internal/cmd/beta/kms/version/destroy/destroy.go b/internal/cmd/beta/kms/version/destroy/destroy.go index d7853e912..d5955690d 100644 --- a/internal/cmd/beta/kms/version/destroy/destroy.go +++ b/internal/cmd/beta/kms/version/destroy/destroy.go @@ -140,7 +140,7 @@ func outputResult(p *print.Printer, outputFormat string, resp *kms.Version) erro p.Outputln(string(details)) default: - p.Outputf("Destroyed version %d of key '%s'\n", utils.PtrValue(resp.Number), utils.PtrValue(resp.KeyId)) + p.Outputf("Destroyed version %d of the key '%s'\n", utils.PtrValue(resp.Number), utils.PtrValue(resp.KeyId)) } return nil diff --git a/internal/cmd/beta/kms/version/disable/disable.go b/internal/cmd/beta/kms/version/disable/disable.go index bba692072..abb3be598 100644 --- a/internal/cmd/beta/kms/version/disable/disable.go +++ b/internal/cmd/beta/kms/version/disable/disable.go @@ -142,7 +142,7 @@ func outputResult(p *print.Printer, outputFormat string, resp *kms.Version) erro p.Outputln(string(details)) default: - p.Outputf("Disabled version %d of key '%s'\n", utils.PtrValue(resp.Number), utils.PtrValue(resp.KeyId)) + p.Outputf("Disabled version %d of the key '%s'\n", utils.PtrValue(resp.Number), utils.PtrValue(resp.KeyId)) } return nil diff --git a/internal/cmd/beta/kms/version/enable/enable.go b/internal/cmd/beta/kms/version/enable/enable.go index a8eb35e46..d4d6ce639 100644 --- a/internal/cmd/beta/kms/version/enable/enable.go +++ b/internal/cmd/beta/kms/version/enable/enable.go @@ -153,7 +153,7 @@ func outputResult(p *print.Printer, outputFormat string, resp *kms.Version) erro p.Outputln(string(details)) default: - p.Outputf("Enabled version %d of key '%s'\n", utils.PtrValue(resp.Number), utils.PtrValue(resp.KeyId)) + p.Outputf("Enabled version %d of the key '%s'\n", utils.PtrValue(resp.Number), utils.PtrValue(resp.KeyId)) } return nil diff --git a/internal/cmd/beta/kms/version/restore/restore.go b/internal/cmd/beta/kms/version/restore/restore.go index fea850258..9969de82a 100644 --- a/internal/cmd/beta/kms/version/restore/restore.go +++ b/internal/cmd/beta/kms/version/restore/restore.go @@ -38,7 +38,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { cmd := &cobra.Command{ Use: fmt.Sprintf("restore %s", versionNumberArg), Short: "Restore a key version", - Long: "Restores the specified version of key.", + Long: "Restores the specified version of a key.", Args: args.SingleArg(versionNumberArg, nil), Example: examples.Build( examples.NewExample( @@ -139,7 +139,7 @@ func outputResult(p *print.Printer, outputFormat string, resp *kms.Version) erro p.Outputln(string(details)) default: - p.Outputf("Restored version %d of key '%s'\n", utils.PtrValue(resp.Number), utils.PtrValue(resp.KeyId)) + p.Outputf("Restored version %d of the key '%s'\n", utils.PtrValue(resp.Number), utils.PtrValue(resp.KeyId)) } return nil } diff --git a/internal/cmd/beta/kms/wrappingkey/create/create.go b/internal/cmd/beta/kms/wrappingkey/create/create.go index ea94d4b9e..d16658059 100644 --- a/internal/cmd/beta/kms/wrappingkey/create/create.go +++ b/internal/cmd/beta/kms/wrappingkey/create/create.go @@ -51,10 +51,10 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Args: args.NoArgs, Example: examples.Build( examples.NewExample( - `Create a symmetric (RSA + AES) KMS wrapping key with name "my-wrapping-key-name" in keyring with ID "MY_KEYRING_ID"`, + `Create a symmetric (RSA + AES) KMS wrapping key with name "my-wrapping-key-name" in key ring with ID "MY_KEYRING_ID"`, `$ stackit beta kms wrapping-key create --keyring-id "MY_KEYRING_ID" --algorithm "rsa_2048_oaep_sha256_aes_256_key_wrap" --name "my-wrapping-key-name" --purpose "wrap_symmetric_key" --protection "software"`), examples.NewExample( - `Create an asymmetric (RSA) KMS wrapping key with name "my-wrapping-key-name" in keyring with ID "MY_KEYRING_ID"`, + `Create an asymmetric (RSA) KMS wrapping key with name "my-wrapping-key-name" in key ring with ID "MY_KEYRING_ID"`, `$ stackit beta kms wrapping-key create --keyring-id "MY_KEYRING_ID" --algorithm "rsa_3072_oaep_sha256" --name "my-wrapping-key-name" --purpose "wrap_asymmetric_key" --protection "software"`), ), RunE: func(cmd *cobra.Command, _ []string) error { diff --git a/internal/cmd/beta/kms/wrappingkey/list/list.go b/internal/cmd/beta/kms/wrappingkey/list/list.go index a71665952..d2462a94b 100644 --- a/internal/cmd/beta/kms/wrappingkey/list/list.go +++ b/internal/cmd/beta/kms/wrappingkey/list/list.go @@ -41,7 +41,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { `$ stackit beta kms wrapping-key list --keyring-id "MY_KEYRING_ID"`), examples.NewExample( `List all KMS wrapping keys in JSON format`, - `$ stackit beta kms wrappingkeys list --keyring-id "MY_KEYRING_ID" --output-format json`), + `$ stackit beta kms wrapping-key list --keyring-id "MY_KEYRING_ID" --output-format json`), ), RunE: func(cmd *cobra.Command, _ []string) error { ctx := context.Background() @@ -92,7 +92,7 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *kms.APIClie } func configureFlags(cmd *cobra.Command) { - cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS Key Ring where the Key is stored") + cmd.Flags().Var(flags.UUIDFlag(), keyRingIdFlag, "ID of the KMS key ring where the key is stored") err := flags.MarkFlagsRequired(cmd, keyRingIdFlag) cobra.CheckErr(err) } diff --git a/internal/pkg/services/kms/utils/utils.go b/internal/pkg/services/kms/utils/utils.go index f1927924b..5630e27d6 100644 --- a/internal/pkg/services/kms/utils/utils.go +++ b/internal/pkg/services/kms/utils/utils.go @@ -43,7 +43,7 @@ func GetKeyDeletionDate(ctx context.Context, apiClient KMSClient, projectId, reg func GetKeyRingName(ctx context.Context, apiClient KMSClient, projectId, id, region string) (string, error) { resp, err := apiClient.GetKeyRingExecute(ctx, projectId, region, id) if err != nil { - return "", fmt.Errorf("get KMS Key Ring: %w", err) + return "", fmt.Errorf("get KMS key ring: %w", err) } if resp == nil || resp.DisplayName == nil { From 9b79a43d2e51dc209f892150000ff688bccc5e42 Mon Sep 17 00:00:00 2001 From: Jan Sternagel Date: Tue, 21 Oct 2025 22:28:27 +0200 Subject: [PATCH 51/52] proper capitalization for flag and argument examples & typos & nitpicks --- docs/stackit_beta_kms_key_create.md | 14 +++++++------- docs/stackit_beta_kms_key_delete.md | 4 ++-- docs/stackit_beta_kms_key_import.md | 4 ++-- docs/stackit_beta_kms_key_list.md | 6 +++--- docs/stackit_beta_kms_key_restore.md | 4 ++-- docs/stackit_beta_kms_key_rotate.md | 4 ++-- docs/stackit_beta_kms_version_destroy.md | 4 ++-- docs/stackit_beta_kms_version_disable.md | 4 ++-- docs/stackit_beta_kms_version_enable.md | 4 ++-- docs/stackit_beta_kms_version_list.md | 6 +++--- docs/stackit_beta_kms_version_restore.md | 4 ++-- docs/stackit_beta_kms_wrapping-key_create.md | 8 ++++---- docs/stackit_beta_kms_wrapping-key_delete.md | 4 ++-- docs/stackit_beta_kms_wrapping-key_list.md | 6 +++--- ...stackit_beta_sqlserverflex_instance_create.md | 2 +- internal/cmd/beta/kms/key/create/create.go | 16 ++++++++-------- internal/cmd/beta/kms/key/delete/delete.go | 4 ++-- internal/cmd/beta/kms/key/importKey/importKey.go | 4 ++-- internal/cmd/beta/kms/key/list/list.go | 6 +++--- internal/cmd/beta/kms/key/restore/restore.go | 6 +++--- internal/cmd/beta/kms/key/rotate/rotate.go | 4 ++-- internal/cmd/beta/kms/version/destroy/destroy.go | 6 +++--- internal/cmd/beta/kms/version/disable/disable.go | 6 +++--- internal/cmd/beta/kms/version/enable/enable.go | 6 +++--- internal/cmd/beta/kms/version/list/list.go | 6 +++--- internal/cmd/beta/kms/version/restore/restore.go | 6 +++--- .../cmd/beta/kms/wrappingkey/create/create.go | 8 ++++---- .../cmd/beta/kms/wrappingkey/delete/delete.go | 4 ++-- internal/cmd/beta/kms/wrappingkey/list/list.go | 6 +++--- .../beta/sqlserverflex/instance/create/create.go | 2 +- 30 files changed, 84 insertions(+), 84 deletions(-) diff --git a/docs/stackit_beta_kms_key_create.md b/docs/stackit_beta_kms_key_create.md index 10fbac43f..0c3114a69 100644 --- a/docs/stackit_beta_kms_key_create.md +++ b/docs/stackit_beta_kms_key_create.md @@ -13,23 +13,23 @@ stackit beta kms key create [flags] ### Examples ``` - Create a symmetric AES key (AES-256) with the name "symm-aes-gcm" under the key ring "MY_KEYRING_ID" - $ stackit beta kms key create --keyring-id "MY_KEYRING_ID" --algorithm "aes_256_gcm" --name "symm-aes-gcm" --purpose "symmetric_encrypt_decrypt" --protection "software" + Create a symmetric AES key (AES-256) with the name "symm-aes-gcm" under the key ring "my-keyring-id" + $ stackit beta kms key create --keyring-id "my-keyring-id" --algorithm "aes_256_gcm" --name "symm-aes-gcm" --purpose "symmetric_encrypt_decrypt" --protection "software" Create an asymmetric RSA encryption key (RSA-2048) - $ stackit beta kms key create --keyring-id "MY_KEYRING_ID" --algorithm "rsa_2048_oaep_sha256" --name "prod-orders-rsa" --purpose "asymmetric_encrypt_decrypt" --protection "software" + $ stackit beta kms key create --keyring-id "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "prod-orders-rsa" --purpose "asymmetric_encrypt_decrypt" --protection "software" Create a message authentication key (HMAC-SHA512) - $ stackit beta kms key create --keyring-id "MY_KEYRING_ID" --algorithm "hmac_sha512" --name "api-mac-key" --purpose "message_authentication_code" --protection "software" + $ stackit beta kms key create --keyring-id "my-keyring-id" --algorithm "hmac_sha512" --name "api-mac-key" --purpose "message_authentication_code" --protection "software" Create an ECDSA P-256 key for signing & verification - $ stackit beta kms key create --keyring-id "MY_KEYRING_ID" --algorithm "ecdsa_p256_sha256" --name "signing-ecdsa-p256" --purpose "asymmetric_sign_verify" --protection "software" + $ stackit beta kms key create --keyring-id "my-keyring-id" --algorithm "ecdsa_p256_sha256" --name "signing-ecdsa-p256" --purpose "asymmetric_sign_verify" --protection "software" Create an import-only key (versions must be imported) - $ stackit beta kms key create --keyring-id "MY_KEYRING_ID" --algorithm "rsa_2048_oaep_sha256" --name "ext-managed-rsa" --purpose "asymmetric_encrypt_decrypt" --protection "software" --import-only + $ stackit beta kms key create --keyring-id "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "ext-managed-rsa" --purpose "asymmetric_encrypt_decrypt" --protection "software" --import-only Create a key and print the result as YAML - $ stackit beta kms key create --keyring-id "MY_KEYRING_ID" --algorithm "rsa_2048_oaep_sha256" --name "yaml-output-rsa" --purpose "asymmetric_encrypt_decrypt" --protection "software" --output yaml + $ stackit beta kms key create --keyring-id "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "yaml-output-rsa" --purpose "asymmetric_encrypt_decrypt" --protection "software" --output yaml ``` ### Options diff --git a/docs/stackit_beta_kms_key_delete.md b/docs/stackit_beta_kms_key_delete.md index 55f7cd1d7..1f67c4ff8 100644 --- a/docs/stackit_beta_kms_key_delete.md +++ b/docs/stackit_beta_kms_key_delete.md @@ -13,8 +13,8 @@ stackit beta kms key delete KEY_ID [flags] ### Examples ``` - Delete a KMS key "MY_KEY_ID" inside the key ring "MY_KEYRING_ID" - $ stackit beta kms key delete "MY_KEY_ID" --keyring-id "MY_KEYRING_ID" + Delete a KMS key "MY_KEY_ID" inside the key ring "my-keyring-id" + $ stackit beta kms key delete "MY_KEY_ID" --keyring-id "my-keyring-id" ``` ### Options diff --git a/docs/stackit_beta_kms_key_import.md b/docs/stackit_beta_kms_key_import.md index fe4af56d5..efc1ba47a 100644 --- a/docs/stackit_beta_kms_key_import.md +++ b/docs/stackit_beta_kms_key_import.md @@ -14,10 +14,10 @@ stackit beta kms key import KEY_ID [flags] ``` Import a new version for the given KMS key "MY_KEY_ID" from literal value - $ stackit beta kms key import "MY_KEY_ID" --keyring-id "MY_KEYRING_ID" --wrapped-key "BASE64_VALUE" --wrapping-key-id "MY_WRAPPING_KEY_ID" + $ stackit beta kms key import "MY_KEY_ID" --keyring-id "my-keyring-id" --wrapped-key "BASE64_VALUE" --wrapping-key-id "MY_WRAPPING_KEY_ID" Import from a file - $ stackit beta kms key import "MY_KEY_ID" --keyring-id "MY_KEYRING_ID" --wrapped-key "@path/to/wrapped.key.b64" --wrapping-key-id "MY_WRAPPING_KEY_ID" + $ stackit beta kms key import "MY_KEY_ID" --keyring-id "my-keyring-id" --wrapped-key "@path/to/wrapped.key.b64" --wrapping-key-id "MY_WRAPPING_KEY_ID" ``` ### Options diff --git a/docs/stackit_beta_kms_key_list.md b/docs/stackit_beta_kms_key_list.md index 3feb8c189..766bb0a5d 100644 --- a/docs/stackit_beta_kms_key_list.md +++ b/docs/stackit_beta_kms_key_list.md @@ -13,11 +13,11 @@ stackit beta kms key list [flags] ### Examples ``` - List all KMS keys for the key ring "MY_KEYRING_ID" - $ stackit beta kms key list --keyring-id "MY_KEYRING_ID" + List all KMS keys for the key ring "my-keyring-id" + $ stackit beta kms key list --keyring-id "my-keyring-id" List all KMS keys in JSON format - $ stackit beta kms key list --keyring-id "MY_KEYRING_ID" --output-format json + $ stackit beta kms key list --keyring-id "my-keyring-id" --output-format json ``` ### Options diff --git a/docs/stackit_beta_kms_key_restore.md b/docs/stackit_beta_kms_key_restore.md index 689248fe2..9abd9a85e 100644 --- a/docs/stackit_beta_kms_key_restore.md +++ b/docs/stackit_beta_kms_key_restore.md @@ -13,8 +13,8 @@ stackit beta kms key restore KEY_ID [flags] ### Examples ``` - Restore a KMS key "MY_KEY_ID" inside the key ring "MY_KEYRING_ID" that was scheduled for deletion. - $ stackit beta kms key restore "MY_KEY_ID" --keyring-id "MY_KEYRING_ID" + Restore a KMS key "MY_KEY_ID" inside the key ring "my-keyring-id" that was scheduled for deletion. + $ stackit beta kms key restore "MY_KEY_ID" --keyring-id "my-keyring-id" ``` ### Options diff --git a/docs/stackit_beta_kms_key_rotate.md b/docs/stackit_beta_kms_key_rotate.md index e6cc22630..7fdbbe3c5 100644 --- a/docs/stackit_beta_kms_key_rotate.md +++ b/docs/stackit_beta_kms_key_rotate.md @@ -13,8 +13,8 @@ stackit beta kms key rotate KEY_ID [flags] ### Examples ``` - Rotate a KMS key "MY_KEY_ID" and increase its version inside the key ring "MY_KEYRING_ID". - $ stackit beta kms key rotate "MY_KEY_ID" --keyring-id "MY_KEYRING_ID" + Rotate a KMS key "MY_KEY_ID" and increase its version inside the key ring "my-keyring-id". + $ stackit beta kms key rotate "MY_KEY_ID" --keyring-id "my-keyring-id" ``` ### Options diff --git a/docs/stackit_beta_kms_version_destroy.md b/docs/stackit_beta_kms_version_destroy.md index e330b50d3..8a189ecf2 100644 --- a/docs/stackit_beta_kms_version_destroy.md +++ b/docs/stackit_beta_kms_version_destroy.md @@ -13,8 +13,8 @@ stackit beta kms version destroy VERSION_NUMBER [flags] ### Examples ``` - Destroy key version "42" for the key "MY_KEY_ID" inside the key ring "MY_KEYRING_ID" - $ stackit beta kms version destroy 42 --key-id "MY_KEY_ID" --keyring-id "MY_KEYRING_ID" + Destroy key version "42" for the key "my-key-id" inside the key ring "my-keyring-id" + $ stackit beta kms version destroy 42 --key-id "my-key-id" --keyring-id "my-keyring-id" ``` ### Options diff --git a/docs/stackit_beta_kms_version_disable.md b/docs/stackit_beta_kms_version_disable.md index 114c2996a..c2e13a87e 100644 --- a/docs/stackit_beta_kms_version_disable.md +++ b/docs/stackit_beta_kms_version_disable.md @@ -13,8 +13,8 @@ stackit beta kms version disable VERSION_NUMBER [flags] ### Examples ``` - Disable key version "42" for the key "MY_KEY_ID" inside the key ring "MY_KEYRING_ID" - $ stackit beta kms version disable 42 --key-id "MY_KEY_ID" --keyring-id "MY_KEYRING_ID" + Disable key version "42" for the key "my-key-id" inside the key ring "my-keyring-id" + $ stackit beta kms version disable 42 --key-id "my-key-id" --keyring-id "my-keyring-id" ``` ### Options diff --git a/docs/stackit_beta_kms_version_enable.md b/docs/stackit_beta_kms_version_enable.md index 9b992ecac..46d23bec0 100644 --- a/docs/stackit_beta_kms_version_enable.md +++ b/docs/stackit_beta_kms_version_enable.md @@ -13,8 +13,8 @@ stackit beta kms version enable VERSION_NUMBER [flags] ### Examples ``` - Enable key version "42" for the key "MY_KEY_ID" inside the key ring "MY_KEYRING_ID" - $ stackit beta kms version enable 42 --key-id "MY_KEY_ID" --keyring-id "MY_KEYRING_ID" + Enable key version "42" for the key "my-key-id" inside the key ring "my-keyring-id" + $ stackit beta kms version enable 42 --key-id "my-key-id" --keyring-id "my-keyring-id" ``` ### Options diff --git a/docs/stackit_beta_kms_version_list.md b/docs/stackit_beta_kms_version_list.md index d1950d700..bd4a96747 100644 --- a/docs/stackit_beta_kms_version_list.md +++ b/docs/stackit_beta_kms_version_list.md @@ -13,11 +13,11 @@ stackit beta kms version list [flags] ### Examples ``` - List all key versions for the key "MY_KEY_ID" inside the key ring "MY_KEYRING_ID" - $ stackit beta kms version list --key-id "MY_KEY_ID" --keyring-id "MY_KEYRING_ID" + List all key versions for the key "my-key-id" inside the key ring "my-keyring-id" + $ stackit beta kms version list --key-id "my-key-id" --keyring-id "my-keyring-id" List all key versions in JSON format - $ stackit beta kms version list --key-id "MY_KEY_ID" --keyring-id "MY_KEYRING_ID" -o json + $ stackit beta kms version list --key-id "my-key-id" --keyring-id "my-keyring-id" -o json ``` ### Options diff --git a/docs/stackit_beta_kms_version_restore.md b/docs/stackit_beta_kms_version_restore.md index 303774724..1562d5fa2 100644 --- a/docs/stackit_beta_kms_version_restore.md +++ b/docs/stackit_beta_kms_version_restore.md @@ -13,8 +13,8 @@ stackit beta kms version restore VERSION_NUMBER [flags] ### Examples ``` - Restore key version "42" for the key "MY_KEY_ID" inside the key ring "MY_KEYRING_ID" - $ stackit beta kms version restore 42 --key-id "MY_KEY_ID" --keyring-id "MY_KEYRING_ID" + Restore key version "42" for the key "my-key-id" inside the key ring "my-keyring-id" + $ stackit beta kms version restore 42 --key-id "my-key-id" --keyring-id "my-keyring-id" ``` ### Options diff --git a/docs/stackit_beta_kms_wrapping-key_create.md b/docs/stackit_beta_kms_wrapping-key_create.md index 8c6a78a1a..d4087bcbe 100644 --- a/docs/stackit_beta_kms_wrapping-key_create.md +++ b/docs/stackit_beta_kms_wrapping-key_create.md @@ -13,11 +13,11 @@ stackit beta kms wrapping-key create [flags] ### Examples ``` - Create a symmetric (RSA + AES) KMS wrapping key with name "my-wrapping-key-name" in key ring with ID "MY_KEYRING_ID" - $ stackit beta kms wrapping-key create --keyring-id "MY_KEYRING_ID" --algorithm "rsa_2048_oaep_sha256_aes_256_key_wrap" --name "my-wrapping-key-name" --purpose "wrap_symmetric_key" --protection "software" + Create a symmetric (RSA + AES) KMS wrapping key with name "my-wrapping-key-name" in key ring with ID "my-keyring-id" + $ stackit beta kms wrapping-key create --keyring-id "my-keyring-id" --algorithm "rsa_2048_oaep_sha256_aes_256_key_wrap" --name "my-wrapping-key-name" --purpose "wrap_symmetric_key" --protection "software" - Create an asymmetric (RSA) KMS wrapping key with name "my-wrapping-key-name" in key ring with ID "MY_KEYRING_ID" - $ stackit beta kms wrapping-key create --keyring-id "MY_KEYRING_ID" --algorithm "rsa_3072_oaep_sha256" --name "my-wrapping-key-name" --purpose "wrap_asymmetric_key" --protection "software" + Create an asymmetric (RSA) KMS wrapping key with name "my-wrapping-key-name" in key ring with ID "my-keyring-id" + $ stackit beta kms wrapping-key create --keyring-id "my-keyring-id" --algorithm "rsa_3072_oaep_sha256" --name "my-wrapping-key-name" --purpose "wrap_asymmetric_key" --protection "software" ``` ### Options diff --git a/docs/stackit_beta_kms_wrapping-key_delete.md b/docs/stackit_beta_kms_wrapping-key_delete.md index dce6cf824..0dfd43a03 100644 --- a/docs/stackit_beta_kms_wrapping-key_delete.md +++ b/docs/stackit_beta_kms_wrapping-key_delete.md @@ -13,8 +13,8 @@ stackit beta kms wrapping-key delete WRAPPING_KEY_ID [flags] ### Examples ``` - Delete a KMS wrapping key "MY_WRAPPING_KEY_ID" inside the key ring "MY_KEYRING_ID" - $ stackit beta kms wrapping-key delete "MY_WRAPPING_KEY_ID" --keyring-id "MY_KEYRING_ID" + Delete a KMS wrapping key "MY_WRAPPING_KEY_ID" inside the key ring "my-keyring-id" + $ stackit beta kms wrapping-key delete "MY_WRAPPING_KEY_ID" --keyring-id "my-keyring-id" ``` ### Options diff --git a/docs/stackit_beta_kms_wrapping-key_list.md b/docs/stackit_beta_kms_wrapping-key_list.md index 89cf7f99f..f17c23212 100644 --- a/docs/stackit_beta_kms_wrapping-key_list.md +++ b/docs/stackit_beta_kms_wrapping-key_list.md @@ -13,11 +13,11 @@ stackit beta kms wrapping-key list [flags] ### Examples ``` - List all KMS wrapping keys for the key ring "MY_KEYRING_ID" - $ stackit beta kms wrapping-key list --keyring-id "MY_KEYRING_ID" + List all KMS wrapping keys for the key ring "my-keyring-id" + $ stackit beta kms wrapping-key list --keyring-id "my-keyring-id" List all KMS wrapping keys in JSON format - $ stackit beta kms wrapping-key list --keyring-id "MY_KEYRING_ID" --output-format json + $ stackit beta kms wrapping-key list --keyring-id "my-keyring-id" --output-format json ``` ### Options diff --git a/docs/stackit_beta_sqlserverflex_instance_create.md b/docs/stackit_beta_sqlserverflex_instance_create.md index 6e8dc16a0..b297bf7b0 100644 --- a/docs/stackit_beta_sqlserverflex_instance_create.md +++ b/docs/stackit_beta_sqlserverflex_instance_create.md @@ -21,7 +21,7 @@ stackit beta sqlserverflex instance create [flags] $ stackit beta sqlserverflex instance create --name my-instance --flavor-id xxx Create a SQLServer Flex instance with name "my-instance", specify flavor by CPU and RAM, set storage size to 20 GB, and restrict access to a specific range of IP addresses. Other parameters are set to default values - $ stackit beta sqlserverflex instance create --name my-instance --cpu 1 --ram 4 --storage-size 20 --acl 1.2.3.0/24 + $ stackit beta sqlserverflex instance create --name my-instance --cpu 1 --ram 4 --storage-size 20 --acl 1.2.3.0/24 ``` ### Options diff --git a/internal/cmd/beta/kms/key/create/create.go b/internal/cmd/beta/kms/key/create/create.go index a3e1f8eea..1d815e638 100644 --- a/internal/cmd/beta/kms/key/create/create.go +++ b/internal/cmd/beta/kms/key/create/create.go @@ -53,23 +53,23 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Args: args.NoArgs, Example: examples.Build( examples.NewExample( - `Create a symmetric AES key (AES-256) with the name "symm-aes-gcm" under the key ring "MY_KEYRING_ID"`, - `$ stackit beta kms key create --keyring-id "MY_KEYRING_ID" --algorithm "aes_256_gcm" --name "symm-aes-gcm" --purpose "symmetric_encrypt_decrypt" --protection "software"`), + `Create a symmetric AES key (AES-256) with the name "symm-aes-gcm" under the key ring "my-keyring-id"`, + `$ stackit beta kms key create --keyring-id "my-keyring-id" --algorithm "aes_256_gcm" --name "symm-aes-gcm" --purpose "symmetric_encrypt_decrypt" --protection "software"`), examples.NewExample( `Create an asymmetric RSA encryption key (RSA-2048)`, - `$ stackit beta kms key create --keyring-id "MY_KEYRING_ID" --algorithm "rsa_2048_oaep_sha256" --name "prod-orders-rsa" --purpose "asymmetric_encrypt_decrypt" --protection "software"`), + `$ stackit beta kms key create --keyring-id "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "prod-orders-rsa" --purpose "asymmetric_encrypt_decrypt" --protection "software"`), examples.NewExample( `Create a message authentication key (HMAC-SHA512)`, - `$ stackit beta kms key create --keyring-id "MY_KEYRING_ID" --algorithm "hmac_sha512" --name "api-mac-key" --purpose "message_authentication_code" --protection "software"`), + `$ stackit beta kms key create --keyring-id "my-keyring-id" --algorithm "hmac_sha512" --name "api-mac-key" --purpose "message_authentication_code" --protection "software"`), examples.NewExample( `Create an ECDSA P-256 key for signing & verification`, - `$ stackit beta kms key create --keyring-id "MY_KEYRING_ID" --algorithm "ecdsa_p256_sha256" --name "signing-ecdsa-p256" --purpose "asymmetric_sign_verify" --protection "software"`), + `$ stackit beta kms key create --keyring-id "my-keyring-id" --algorithm "ecdsa_p256_sha256" --name "signing-ecdsa-p256" --purpose "asymmetric_sign_verify" --protection "software"`), examples.NewExample( `Create an import-only key (versions must be imported)`, - `$ stackit beta kms key create --keyring-id "MY_KEYRING_ID" --algorithm "rsa_2048_oaep_sha256" --name "ext-managed-rsa" --purpose "asymmetric_encrypt_decrypt" --protection "software" --import-only`), + `$ stackit beta kms key create --keyring-id "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "ext-managed-rsa" --purpose "asymmetric_encrypt_decrypt" --protection "software" --import-only`), examples.NewExample( `Create a key and print the result as YAML`, - `$ stackit beta kms key create --keyring-id "MY_KEYRING_ID" --algorithm "rsa_2048_oaep_sha256" --name "yaml-output-rsa" --purpose "asymmetric_encrypt_decrypt" --protection "software" --output yaml`), + `$ stackit beta kms key create --keyring-id "my-keyring-id" --algorithm "rsa_2048_oaep_sha256" --name "yaml-output-rsa" --purpose "asymmetric_encrypt_decrypt" --protection "software" --output yaml`), ), RunE: func(cmd *cobra.Command, _ []string) error { ctx := context.Background() @@ -180,7 +180,7 @@ func outputResult(p *print.Printer, model *inputModel, resp *kms.Key) error { if model.Async { operationState = "Triggered creation of" } - p.Outputf("%s the KMS key '%s'. Key ID: %s\n", operationState, utils.PtrString(resp.DisplayName), utils.PtrString(resp.Id)) + p.Outputf("%s the KMS key %q. Key ID: %s\n", operationState, utils.PtrString(resp.DisplayName), utils.PtrString(resp.Id)) } return nil } diff --git a/internal/cmd/beta/kms/key/delete/delete.go b/internal/cmd/beta/kms/key/delete/delete.go index 487b315c9..56ab3059a 100644 --- a/internal/cmd/beta/kms/key/delete/delete.go +++ b/internal/cmd/beta/kms/key/delete/delete.go @@ -41,8 +41,8 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Args: args.SingleArg(keyIdArg, utils.ValidateUUID), Example: examples.Build( examples.NewExample( - `Delete a KMS key "MY_KEY_ID" inside the key ring "MY_KEYRING_ID"`, - `$ stackit beta kms key delete "MY_KEY_ID" --keyring-id "MY_KEYRING_ID"`), + `Delete a KMS key "MY_KEY_ID" inside the key ring "my-keyring-id"`, + `$ stackit beta kms key delete "MY_KEY_ID" --keyring-id "my-keyring-id"`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/key/importKey/importKey.go b/internal/cmd/beta/kms/key/importKey/importKey.go index c8cf7d7ed..f491f6eb7 100644 --- a/internal/cmd/beta/kms/key/importKey/importKey.go +++ b/internal/cmd/beta/kms/key/importKey/importKey.go @@ -47,10 +47,10 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Example: examples.Build( examples.NewExample( `Import a new version for the given KMS key "MY_KEY_ID" from literal value`, - `$ stackit beta kms key import "MY_KEY_ID" --keyring-id "MY_KEYRING_ID" --wrapped-key "BASE64_VALUE" --wrapping-key-id "MY_WRAPPING_KEY_ID"`), + `$ stackit beta kms key import "MY_KEY_ID" --keyring-id "my-keyring-id" --wrapped-key "BASE64_VALUE" --wrapping-key-id "MY_WRAPPING_KEY_ID"`), examples.NewExample( `Import from a file`, - `$ stackit beta kms key import "MY_KEY_ID" --keyring-id "MY_KEYRING_ID" --wrapped-key "@path/to/wrapped.key.b64" --wrapping-key-id "MY_WRAPPING_KEY_ID"`, + `$ stackit beta kms key import "MY_KEY_ID" --keyring-id "my-keyring-id" --wrapped-key "@path/to/wrapped.key.b64" --wrapping-key-id "MY_WRAPPING_KEY_ID"`, ), ), diff --git a/internal/cmd/beta/kms/key/list/list.go b/internal/cmd/beta/kms/key/list/list.go index 43d3dd62c..aa337b5b7 100644 --- a/internal/cmd/beta/kms/key/list/list.go +++ b/internal/cmd/beta/kms/key/list/list.go @@ -37,11 +37,11 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Args: args.NoArgs, Example: examples.Build( examples.NewExample( - `List all KMS keys for the key ring "MY_KEYRING_ID"`, - `$ stackit beta kms key list --keyring-id "MY_KEYRING_ID"`), + `List all KMS keys for the key ring "my-keyring-id"`, + `$ stackit beta kms key list --keyring-id "my-keyring-id"`), examples.NewExample( `List all KMS keys in JSON format`, - `$ stackit beta kms key list --keyring-id "MY_KEYRING_ID" --output-format json`), + `$ stackit beta kms key list --keyring-id "my-keyring-id" --output-format json`), ), RunE: func(cmd *cobra.Command, _ []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/key/restore/restore.go b/internal/cmd/beta/kms/key/restore/restore.go index 0dd240a65..05494a97a 100644 --- a/internal/cmd/beta/kms/key/restore/restore.go +++ b/internal/cmd/beta/kms/key/restore/restore.go @@ -41,8 +41,8 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Args: args.SingleArg(keyIdArg, utils.ValidateUUID), Example: examples.Build( examples.NewExample( - `Restore a KMS key "MY_KEY_ID" inside the key ring "MY_KEYRING_ID" that was scheduled for deletion.`, - `$ stackit beta kms key restore "MY_KEY_ID" --keyring-id "MY_KEYRING_ID"`), + `Restore a KMS key "MY_KEY_ID" inside the key ring "my-keyring-id" that was scheduled for deletion.`, + `$ stackit beta kms key restore "MY_KEY_ID" --keyring-id "my-keyring-id"`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() @@ -142,7 +142,7 @@ func outputResult(p *print.Printer, outputFormat string, resp *kms.Key) error { p.Outputln(string(details)) default: - p.Outputf("Successfully restored KMS key '%s'\n", utils.PtrString(resp.DisplayName)) + p.Outputf("Successfully restored KMS key %q\n", utils.PtrString(resp.DisplayName)) } return nil } diff --git a/internal/cmd/beta/kms/key/rotate/rotate.go b/internal/cmd/beta/kms/key/rotate/rotate.go index e0523d2fc..14e4ff15f 100644 --- a/internal/cmd/beta/kms/key/rotate/rotate.go +++ b/internal/cmd/beta/kms/key/rotate/rotate.go @@ -41,8 +41,8 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Args: args.SingleArg(keyIdArg, utils.ValidateUUID), Example: examples.Build( examples.NewExample( - `Rotate a KMS key "MY_KEY_ID" and increase its version inside the key ring "MY_KEYRING_ID".`, - `$ stackit beta kms key rotate "MY_KEY_ID" --keyring-id "MY_KEYRING_ID"`), + `Rotate a KMS key "MY_KEY_ID" and increase its version inside the key ring "my-keyring-id".`, + `$ stackit beta kms key rotate "MY_KEY_ID" --keyring-id "my-keyring-id"`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/version/destroy/destroy.go b/internal/cmd/beta/kms/version/destroy/destroy.go index d5955690d..470099c66 100644 --- a/internal/cmd/beta/kms/version/destroy/destroy.go +++ b/internal/cmd/beta/kms/version/destroy/destroy.go @@ -42,8 +42,8 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Args: args.SingleArg(versionNumberArg, nil), Example: examples.Build( examples.NewExample( - `Destroy key version "42" for the key "MY_KEY_ID" inside the key ring "MY_KEYRING_ID"`, - `$ stackit beta kms version destroy 42 --key-id "MY_KEY_ID" --keyring-id "MY_KEYRING_ID"`), + `Destroy key version "42" for the key "my-key-id" inside the key ring "my-keyring-id"`, + `$ stackit beta kms version destroy 42 --key-id "my-key-id" --keyring-id "my-keyring-id"`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() @@ -140,7 +140,7 @@ func outputResult(p *print.Printer, outputFormat string, resp *kms.Version) erro p.Outputln(string(details)) default: - p.Outputf("Destroyed version %d of the key '%s'\n", utils.PtrValue(resp.Number), utils.PtrValue(resp.KeyId)) + p.Outputf("Destroyed version %d of the key %q\n", utils.PtrValue(resp.Number), utils.PtrValue(resp.KeyId)) } return nil diff --git a/internal/cmd/beta/kms/version/disable/disable.go b/internal/cmd/beta/kms/version/disable/disable.go index abb3be598..095a870e4 100644 --- a/internal/cmd/beta/kms/version/disable/disable.go +++ b/internal/cmd/beta/kms/version/disable/disable.go @@ -42,8 +42,8 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Args: args.SingleArg(versionNumberArg, nil), Example: examples.Build( examples.NewExample( - `Disable key version "42" for the key "MY_KEY_ID" inside the key ring "MY_KEYRING_ID"`, - `$ stackit beta kms version disable 42 --key-id "MY_KEY_ID" --keyring-id "MY_KEYRING_ID"`), + `Disable key version "42" for the key "my-key-id" inside the key ring "my-keyring-id"`, + `$ stackit beta kms version disable 42 --key-id "my-key-id" --keyring-id "my-keyring-id"`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() @@ -142,7 +142,7 @@ func outputResult(p *print.Printer, outputFormat string, resp *kms.Version) erro p.Outputln(string(details)) default: - p.Outputf("Disabled version %d of the key '%s'\n", utils.PtrValue(resp.Number), utils.PtrValue(resp.KeyId)) + p.Outputf("Disabled version %d of the key %q\n", utils.PtrValue(resp.Number), utils.PtrValue(resp.KeyId)) } return nil diff --git a/internal/cmd/beta/kms/version/enable/enable.go b/internal/cmd/beta/kms/version/enable/enable.go index d4d6ce639..a2530996c 100644 --- a/internal/cmd/beta/kms/version/enable/enable.go +++ b/internal/cmd/beta/kms/version/enable/enable.go @@ -44,8 +44,8 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Args: args.SingleArg(versionNumberArg, nil), Example: examples.Build( examples.NewExample( - `Enable key version "42" for the key "MY_KEY_ID" inside the key ring "MY_KEYRING_ID"`, - `$ stackit beta kms version enable 42 --key-id "MY_KEY_ID" --keyring-id "MY_KEYRING_ID"`), + `Enable key version "42" for the key "my-key-id" inside the key ring "my-keyring-id"`, + `$ stackit beta kms version enable 42 --key-id "my-key-id" --keyring-id "my-keyring-id"`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() @@ -153,7 +153,7 @@ func outputResult(p *print.Printer, outputFormat string, resp *kms.Version) erro p.Outputln(string(details)) default: - p.Outputf("Enabled version %d of the key '%s'\n", utils.PtrValue(resp.Number), utils.PtrValue(resp.KeyId)) + p.Outputf("Enabled version %d of the key %q\n", utils.PtrValue(resp.Number), utils.PtrValue(resp.KeyId)) } return nil diff --git a/internal/cmd/beta/kms/version/list/list.go b/internal/cmd/beta/kms/version/list/list.go index 21a618e6e..c73b2a949 100644 --- a/internal/cmd/beta/kms/version/list/list.go +++ b/internal/cmd/beta/kms/version/list/list.go @@ -39,11 +39,11 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Args: args.NoArgs, Example: examples.Build( examples.NewExample( - `List all key versions for the key "MY_KEY_ID" inside the key ring "MY_KEYRING_ID"`, - `$ stackit beta kms version list --key-id "MY_KEY_ID" --keyring-id "MY_KEYRING_ID"`), + `List all key versions for the key "my-key-id" inside the key ring "my-keyring-id"`, + `$ stackit beta kms version list --key-id "my-key-id" --keyring-id "my-keyring-id"`), examples.NewExample( `List all key versions in JSON format`, - `$ stackit beta kms version list --key-id "MY_KEY_ID" --keyring-id "MY_KEYRING_ID" -o json`), + `$ stackit beta kms version list --key-id "my-key-id" --keyring-id "my-keyring-id" -o json`), ), RunE: func(cmd *cobra.Command, _ []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/version/restore/restore.go b/internal/cmd/beta/kms/version/restore/restore.go index 9969de82a..c5b4e7aec 100644 --- a/internal/cmd/beta/kms/version/restore/restore.go +++ b/internal/cmd/beta/kms/version/restore/restore.go @@ -42,8 +42,8 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Args: args.SingleArg(versionNumberArg, nil), Example: examples.Build( examples.NewExample( - `Restore key version "42" for the key "MY_KEY_ID" inside the key ring "MY_KEYRING_ID"`, - `$ stackit beta kms version restore 42 --key-id "MY_KEY_ID" --keyring-id "MY_KEYRING_ID"`), + `Restore key version "42" for the key "my-key-id" inside the key ring "my-keyring-id"`, + `$ stackit beta kms version restore 42 --key-id "my-key-id" --keyring-id "my-keyring-id"`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() @@ -139,7 +139,7 @@ func outputResult(p *print.Printer, outputFormat string, resp *kms.Version) erro p.Outputln(string(details)) default: - p.Outputf("Restored version %d of the key '%s'\n", utils.PtrValue(resp.Number), utils.PtrValue(resp.KeyId)) + p.Outputf("Restored version %d of the key %q\n", utils.PtrValue(resp.Number), utils.PtrValue(resp.KeyId)) } return nil } diff --git a/internal/cmd/beta/kms/wrappingkey/create/create.go b/internal/cmd/beta/kms/wrappingkey/create/create.go index d16658059..76d8be6b5 100644 --- a/internal/cmd/beta/kms/wrappingkey/create/create.go +++ b/internal/cmd/beta/kms/wrappingkey/create/create.go @@ -51,11 +51,11 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Args: args.NoArgs, Example: examples.Build( examples.NewExample( - `Create a symmetric (RSA + AES) KMS wrapping key with name "my-wrapping-key-name" in key ring with ID "MY_KEYRING_ID"`, - `$ stackit beta kms wrapping-key create --keyring-id "MY_KEYRING_ID" --algorithm "rsa_2048_oaep_sha256_aes_256_key_wrap" --name "my-wrapping-key-name" --purpose "wrap_symmetric_key" --protection "software"`), + `Create a symmetric (RSA + AES) KMS wrapping key with name "my-wrapping-key-name" in key ring with ID "my-keyring-id"`, + `$ stackit beta kms wrapping-key create --keyring-id "my-keyring-id" --algorithm "rsa_2048_oaep_sha256_aes_256_key_wrap" --name "my-wrapping-key-name" --purpose "wrap_symmetric_key" --protection "software"`), examples.NewExample( - `Create an asymmetric (RSA) KMS wrapping key with name "my-wrapping-key-name" in key ring with ID "MY_KEYRING_ID"`, - `$ stackit beta kms wrapping-key create --keyring-id "MY_KEYRING_ID" --algorithm "rsa_3072_oaep_sha256" --name "my-wrapping-key-name" --purpose "wrap_asymmetric_key" --protection "software"`), + `Create an asymmetric (RSA) KMS wrapping key with name "my-wrapping-key-name" in key ring with ID "my-keyring-id"`, + `$ stackit beta kms wrapping-key create --keyring-id "my-keyring-id" --algorithm "rsa_3072_oaep_sha256" --name "my-wrapping-key-name" --purpose "wrap_asymmetric_key" --protection "software"`), ), RunE: func(cmd *cobra.Command, _ []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/wrappingkey/delete/delete.go b/internal/cmd/beta/kms/wrappingkey/delete/delete.go index 9151c2563..0ade8822f 100644 --- a/internal/cmd/beta/kms/wrappingkey/delete/delete.go +++ b/internal/cmd/beta/kms/wrappingkey/delete/delete.go @@ -39,8 +39,8 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Args: args.SingleArg(wrappingKeyIdArg, utils.ValidateUUID), Example: examples.Build( examples.NewExample( - `Delete a KMS wrapping key "MY_WRAPPING_KEY_ID" inside the key ring "MY_KEYRING_ID"`, - `$ stackit beta kms wrapping-key delete "MY_WRAPPING_KEY_ID" --keyring-id "MY_KEYRING_ID"`), + `Delete a KMS wrapping key "MY_WRAPPING_KEY_ID" inside the key ring "my-keyring-id"`, + `$ stackit beta kms wrapping-key delete "MY_WRAPPING_KEY_ID" --keyring-id "my-keyring-id"`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/kms/wrappingkey/list/list.go b/internal/cmd/beta/kms/wrappingkey/list/list.go index d2462a94b..a89babc53 100644 --- a/internal/cmd/beta/kms/wrappingkey/list/list.go +++ b/internal/cmd/beta/kms/wrappingkey/list/list.go @@ -37,11 +37,11 @@ func NewCmd(params *params.CmdParams) *cobra.Command { Args: args.NoArgs, Example: examples.Build( examples.NewExample( - `List all KMS wrapping keys for the key ring "MY_KEYRING_ID"`, - `$ stackit beta kms wrapping-key list --keyring-id "MY_KEYRING_ID"`), + `List all KMS wrapping keys for the key ring "my-keyring-id"`, + `$ stackit beta kms wrapping-key list --keyring-id "my-keyring-id"`), examples.NewExample( `List all KMS wrapping keys in JSON format`, - `$ stackit beta kms wrapping-key list --keyring-id "MY_KEYRING_ID" --output-format json`), + `$ stackit beta kms wrapping-key list --keyring-id "my-keyring-id" --output-format json`), ), RunE: func(cmd *cobra.Command, _ []string) error { ctx := context.Background() diff --git a/internal/cmd/beta/sqlserverflex/instance/create/create.go b/internal/cmd/beta/sqlserverflex/instance/create/create.go index cc5f2214d..8e349c6bc 100644 --- a/internal/cmd/beta/sqlserverflex/instance/create/create.go +++ b/internal/cmd/beta/sqlserverflex/instance/create/create.go @@ -80,7 +80,7 @@ func NewCmd(params *params.CmdParams) *cobra.Command { `$ stackit beta sqlserverflex instance create --name my-instance --flavor-id xxx`), examples.NewExample( `Create a SQLServer Flex instance with name "my-instance", specify flavor by CPU and RAM, set storage size to 20 GB, and restrict access to a specific range of IP addresses. Other parameters are set to default values`, - `$ stackit beta sqlserverflex instance create --name my-instance --cpu 1 --ram 4 --storage-size 20 --acl 1.2.3.0/24`), + `$ stackit beta sqlserverflex instance create --name my-instance --cpu 1 --ram 4 --storage-size 20 --acl 1.2.3.0/24`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() From 34bf29f02e1117ed2ce99416d1e2629566bc1cd5 Mon Sep 17 00:00:00 2001 From: Jan Sternagel Date: Wed, 22 Oct 2025 11:03:30 +0200 Subject: [PATCH 52/52] Make testRegion const --- internal/pkg/services/kms/utils/utils_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/pkg/services/kms/utils/utils_test.go b/internal/pkg/services/kms/utils/utils_test.go index cefe4cb9c..339cb2d3a 100644 --- a/internal/pkg/services/kms/utils/utils_test.go +++ b/internal/pkg/services/kms/utils/utils_test.go @@ -12,13 +12,13 @@ import ( var ( testProjectId = uuid.NewString() - testRegion = "eu01" testKeyRingId = uuid.NewString() testKeyId = uuid.NewString() testWrappingKeyId = uuid.NewString() ) const ( + testRegion = "eu01" testKeyName = "my-test-key" testKeyRingName = "my-key-ring" testWrappingKeyName = "my-wrapping-key"