From 0413e0c3bc5a6c73199aff53d20d97d903ed6a8e Mon Sep 17 00:00:00 2001 From: TonyAdo <71679464+adohe@users.noreply.github.com> Date: Thu, 21 Dec 2023 19:20:09 +0800 Subject: [PATCH] refactor: use secret types in core v1 pkg (#714) --- pkg/apis/core/v1/workspace.go | 40 ++++++++ pkg/apis/secrets/types.go | 92 ------------------- pkg/secrets/interfaces.go | 6 +- pkg/secrets/providers.go | 8 +- .../alicloud/secretsmanager/secretsmanager.go | 10 +- .../secretsmanager/secretsmanager_test.go | 18 ++-- .../aws/secretsmanager/secretsmanager.go | 12 +-- .../aws/secretsmanager/secretsmanager_test.go | 18 ++-- .../providers/azure/keyvault/keyvault.go | 34 +++---- .../providers/azure/keyvault/keyvault_test.go | 32 +++---- pkg/secrets/providers/hashivault/vault.go | 20 ++-- .../providers/hashivault/vault_test.go | 62 ++++++------- pkg/secrets/providers_test.go | 14 +-- 13 files changed, 157 insertions(+), 209 deletions(-) delete mode 100644 pkg/apis/secrets/types.go diff --git a/pkg/apis/core/v1/workspace.go b/pkg/apis/core/v1/workspace.go index 9298de2d..9b86d917 100644 --- a/pkg/apis/core/v1/workspace.go +++ b/pkg/apis/core/v1/workspace.go @@ -194,6 +194,18 @@ const ( VaultKVStoreV2 VaultKVStoreVersion = "v2" ) +// ExternalSecretRef contains information that points to the secret store data location. +type ExternalSecretRef struct { + // Specifies the name of the secret in Provider to read, mandatory. + Name string `yaml:"name" json:"name"` + + // Specifies the version of the secret to return, if supported. + Version string `yaml:"version,omitempty" json:"version,omitempty"` + + // Used to select a specific property of the secret data (if a map), if supported. + Property string `yaml:"property,omitempty" json:"property,omitempty"` +} + // SecretStoreSpec contains configuration to describe target secret store. type SecretStoreSpec struct { Provider *ProviderSpec `yaml:"provider" json:"provider"` @@ -209,6 +221,9 @@ type ProviderSpec struct { // Vault configures a store to retrieve secrets from HashiCorp Vault. Vault *VaultProvider `yaml:"vault,omitempty" json:"vault,omitempty"` + + // Azure configures a store to retrieve secrets from Azure KeyVault. + Azure *AzureKVProvider `yaml:"azure,omitempty" json:"azure,omitempty"` } // AlicloudProvider configures a store to retrieve secrets from Alicloud Secrets Manager. @@ -241,3 +256,28 @@ type VaultProvider struct { // "v2", defaults to "v2". Version VaultKVStoreVersion `yaml:"version" json:"version"` } + +// AzureEnvironmentType specifies the Azure cloud environment endpoints to use for connecting and authenticating with Azure. +type AzureEnvironmentType string + +const ( + AzureEnvironmentPublicCloud AzureEnvironmentType = "PublicCloud" + AzureEnvironmentUSGovernmentCloud AzureEnvironmentType = "USGovernmentCloud" + AzureEnvironmentChinaCloud AzureEnvironmentType = "ChinaCloud" + AzureEnvironmentGermanCloud AzureEnvironmentType = "GermanCloud" +) + +// AzureKVProvider configures a store to retrieve secrets from Azure KeyVault +type AzureKVProvider struct { + // Vault Url from which the secrets to be fetched from. + VaultURL *string `yaml:"vaultUrl" json:"vaultUrl"` + + // TenantID configures the Azure Tenant to send requests to. + TenantID *string `yaml:"tenantId" json:"tenantId"` + + // EnvironmentType specifies the Azure cloud environment endpoints to use for connecting and authenticating with Azure. + // By-default it points to the public cloud AAD endpoint, and the following endpoints are available: + // PublicCloud, USGovernmentCloud, ChinaCloud, GermanCloud + // Ref: https://github.com/Azure/go-autorest/blob/main/autorest/azure/environments.go#L152 + EnvironmentType AzureEnvironmentType `yaml:"environmentType,omitempty" json:"environmentType,omitempty"` +} diff --git a/pkg/apis/secrets/types.go b/pkg/apis/secrets/types.go deleted file mode 100644 index ecda168d..00000000 --- a/pkg/apis/secrets/types.go +++ /dev/null @@ -1,92 +0,0 @@ -package secrets - -type VaultKVStoreVersion string - -const ( - VaultKVStoreV1 VaultKVStoreVersion = "v1" - VaultKVStoreV2 VaultKVStoreVersion = "v2" -) - -// ExternalSecretRef contains information that points to the secret store data location. -type ExternalSecretRef struct { - // Specifies the name of the secret in Provider to read, mandatory. - Name string `yaml:"name" json:"name"` - - // Specifies the version of the secret to return, if supported. - Version string `yaml:"version,omitempty" json:"version,omitempty"` - - // Used to select a specific property of the secret data (if a map), if supported. - Property string `yaml:"property,omitempty" json:"property,omitempty"` -} - -// SecretStoreSpec contains configuration to describe target secret store. -type SecretStoreSpec struct { - Provider *ProviderSpec `yaml:"provider" json:"provider"` -} - -// ProviderSpec contains provider-specific configuration. -type ProviderSpec struct { - // Alicloud configures a store to retrieve secrets from Alicloud Secrets Manager. - Alicloud *AlicloudProvider `yaml:"alicloud,omitempty" json:"alicloud,omitempty"` - // AWS configures a store to retrieve secrets from AWS Secrets Manager. - AWS *AWSProvider `yaml:"aws,omitempty" json:"aws,omitempty"` - // Vault configures a store to retrieve secrets from HashiCorp Vault. - Vault *VaultProvider `yaml:"vault,omitempty" json:"vault,omitempty"` - // Azure configures a store to retrieve secrets from Azure KeyVault. - Azure *AzureKVProvider `yaml:"azure,omitempty" json:"azure,omitempty"` -} - -// AlicloudProvider configures a store to retrieve secrets from Alicloud Secrets Manager. -type AlicloudProvider struct { - // Alicloud Region to be used to interact with Alicloud Secrets Manager. - // Examples are cn-beijing, cn-shanghai, etc. - Region string `yaml:"region" json:"region"` -} - -// AWSProvider configures a store to retrieve secrets from AWS Secrets Manager. -type AWSProvider struct { - // AWS Region to be used to interact with AWS Secrets Manager. - // Examples are us-east-1, us-west-2, etc. - Region string `yaml:"region" json:"region"` - // The profile to be used to interact with AWS Secrets Manager. - // If not set, the default profile created with `aws configure` will be used. - Profile string `yaml:"profile,omitempty" json:"profile,omitempty"` -} - -// VaultProvider configures a store to retrieve secrets from HashiCorp Vault. -type VaultProvider struct { - // Server is the target Vault server address to connect, e.g: "https://vault.example.com:8200". - Server string `yaml:"server" json:"server"` - - // Path is the mount path of the Vault KV backend endpoint, e.g: "secret". - Path *string `yaml:"path,omitempty" json:"path,omitempty"` - - // Version is the Vault KV secret engine version. Version can be either "v1" or - // "v2", defaults to "v2". - Version VaultKVStoreVersion `yaml:"version" json:"version"` -} - -// AzureEnvironmentType specifies the Azure cloud environment endpoints to use for connecting and authenticating with Azure. -type AzureEnvironmentType string - -const ( - AzureEnvironmentPublicCloud AzureEnvironmentType = "PublicCloud" - AzureEnvironmentUSGovernmentCloud AzureEnvironmentType = "USGovernmentCloud" - AzureEnvironmentChinaCloud AzureEnvironmentType = "ChinaCloud" - AzureEnvironmentGermanCloud AzureEnvironmentType = "GermanCloud" -) - -// AzureKVProvider configures a store to retrieve secrets from Azure KeyVault -type AzureKVProvider struct { - // Vault Url from which the secrets to be fetched from. - VaultURL *string `yaml:"vaultUrl" json:"vaultUrl"` - - // TenantID configures the Azure Tenant to send requests to. - TenantID *string `yaml:"tenantId" json:"tenantId"` - - // EnvironmentType specifies the Azure cloud environment endpoints to use for connecting and authenticating with Azure. - // By-default it points to the public cloud AAD endpoint, and the following endpoints are available: - // PublicCloud, USGovernmentCloud, ChinaCloud, GermanCloud - // Ref: https://github.com/Azure/go-autorest/blob/main/autorest/azure/environments.go#L152 - EnvironmentType AzureEnvironmentType `yaml:"environmentType,omitempty" json:"environmentType,omitempty"` -} diff --git a/pkg/secrets/interfaces.go b/pkg/secrets/interfaces.go index d7fe283b..da42e9f3 100644 --- a/pkg/secrets/interfaces.go +++ b/pkg/secrets/interfaces.go @@ -3,17 +3,17 @@ package secrets import ( "context" - secretsapi "kusionstack.io/kusion/pkg/apis/secrets" + v1 "kusionstack.io/kusion/pkg/apis/core/v1" ) // SecretStore provides the interface to interact with various cloud secret manager. type SecretStore interface { // GetSecret retrieves ref secret from various cloud secret manager. - GetSecret(ctx context.Context, ref secretsapi.ExternalSecretRef) ([]byte, error) + GetSecret(ctx context.Context, ref v1.ExternalSecretRef) ([]byte, error) } // SecretStoreFactory is a factory type for secret store. type SecretStoreFactory interface { // NewSecretStore constructs a usable secret store with specific provider spec. - NewSecretStore(spec secretsapi.SecretStoreSpec) (SecretStore, error) + NewSecretStore(spec v1.SecretStoreSpec) (SecretStore, error) } diff --git a/pkg/secrets/providers.go b/pkg/secrets/providers.go index fa76d649..f8d797f1 100644 --- a/pkg/secrets/providers.go +++ b/pkg/secrets/providers.go @@ -7,7 +7,7 @@ import ( "golang.org/x/exp/maps" - "kusionstack.io/kusion/pkg/apis/secrets" + v1 "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/log" ) @@ -25,7 +25,7 @@ func init() { } // Register a secret store provider with target spec. -func Register(ssf SecretStoreFactory, spec *secrets.ProviderSpec) { +func Register(ssf SecretStoreFactory, spec *v1.ProviderSpec) { secretStoreProviders.register(ssf, spec) } @@ -41,7 +41,7 @@ type Providers struct { // register registers a provider with associated spec. This // is expected to happen during app startup. -func (ps *Providers) register(ssf SecretStoreFactory, spec *secrets.ProviderSpec) { +func (ps *Providers) register(ssf SecretStoreFactory, spec *v1.ProviderSpec) { providerName, err := getProviderName(spec) if err != nil { panic(fmt.Sprintf("provider registery failed to parse spec: %s", err.Error())) @@ -70,7 +70,7 @@ func (ps *Providers) getProviderByName(providerName string) (SecretStoreFactory, return provider, found } -func getProviderName(spec *secrets.ProviderSpec) (string, error) { +func getProviderName(spec *v1.ProviderSpec) (string, error) { specBytes, err := json.Marshal(spec) if err != nil || specBytes == nil { return "", fmt.Errorf("failed to marshal secret store provider spec: %w", err) diff --git a/pkg/secrets/providers/alicloud/secretsmanager/secretsmanager.go b/pkg/secrets/providers/alicloud/secretsmanager/secretsmanager.go index b0733a85..944afad2 100644 --- a/pkg/secrets/providers/alicloud/secretsmanager/secretsmanager.go +++ b/pkg/secrets/providers/alicloud/secretsmanager/secretsmanager.go @@ -6,7 +6,7 @@ import ( "os" "strings" - secretsapi "kusionstack.io/kusion/pkg/apis/secrets" + "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/secrets" "github.com/aliyun/aliyun-secretsmanager-client-go/sdk" @@ -41,7 +41,7 @@ type smSecretStore struct { } // NewSecretStore constructs a Vault based secret store with specific secret store spec. -func (p *DefaultFactory) NewSecretStore(spec secretsapi.SecretStoreSpec) (secrets.SecretStore, error) { +func (p *DefaultFactory) NewSecretStore(spec v1.SecretStoreSpec) (secrets.SecretStore, error) { providerSpec := spec.Provider if providerSpec == nil { return nil, fmt.Errorf(errMissingProviderSpec) @@ -70,7 +70,7 @@ func getAlicloudClient(region string) (*sdk.SecretManagerCacheClient, error) { } // GetSecret retrieves ref secret value from Alicloud Secrets Manager. -func (s *smSecretStore) GetSecret(ctx context.Context, ref secretsapi.ExternalSecretRef) ([]byte, error) { +func (s *smSecretStore) GetSecret(ctx context.Context, ref v1.ExternalSecretRef) ([]byte, error) { secretInfo, err := s.client.GetSecretInfo(ref.Name) if err != nil { return nil, err @@ -115,7 +115,7 @@ func (s *smSecretStore) convertSecretToGjson(secretInfo *models.SecretInfo, refP } func init() { - secrets.Register(&DefaultFactory{}, &secretsapi.ProviderSpec{ - Alicloud: &secretsapi.AlicloudProvider{}, + secrets.Register(&DefaultFactory{}, &v1.ProviderSpec{ + Alicloud: &v1.AlicloudProvider{}, }) } diff --git a/pkg/secrets/providers/alicloud/secretsmanager/secretsmanager_test.go b/pkg/secrets/providers/alicloud/secretsmanager/secretsmanager_test.go index 72ac4673..37292cf4 100644 --- a/pkg/secrets/providers/alicloud/secretsmanager/secretsmanager_test.go +++ b/pkg/secrets/providers/alicloud/secretsmanager/secretsmanager_test.go @@ -9,7 +9,7 @@ import ( "github.com/google/go-cmp/cmp" - secretsapi "kusionstack.io/kusion/pkg/apis/secrets" + "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/secrets/providers/alicloud/secretsmanager/fake" ) @@ -94,7 +94,7 @@ func TestGetSecret(t *testing.T) { for name, tc := range testCases { store := &smSecretStore{client: tc.client} - ref := secretsapi.ExternalSecretRef{ + ref := v1.ExternalSecretRef{ Name: tc.name, Property: tc.property, } @@ -114,23 +114,23 @@ func TestGetSecret(t *testing.T) { func TestNewSecretStore(t *testing.T) { testCases := map[string]struct { - spec secretsapi.SecretStoreSpec + spec v1.SecretStoreSpec expectedErr error }{ "InvalidSecretStoreSpec": { - spec: secretsapi.SecretStoreSpec{}, + spec: v1.SecretStoreSpec{}, expectedErr: errors.New(errMissingProviderSpec), }, "InvalidProviderSpec": { - spec: secretsapi.SecretStoreSpec{ - Provider: &secretsapi.ProviderSpec{}, + spec: v1.SecretStoreSpec{ + Provider: &v1.ProviderSpec{}, }, expectedErr: errors.New(errMissingAlicloudProvider), }, "ValidVaultProviderSpec": { - spec: secretsapi.SecretStoreSpec{ - Provider: &secretsapi.ProviderSpec{ - Alicloud: &secretsapi.AlicloudProvider{ + spec: v1.SecretStoreSpec{ + Provider: &v1.ProviderSpec{ + Alicloud: &v1.AlicloudProvider{ Region: "cn-beijing", }, }, diff --git a/pkg/secrets/providers/aws/secretsmanager/secretsmanager.go b/pkg/secrets/providers/aws/secretsmanager/secretsmanager.go index b236c770..c4745ccf 100644 --- a/pkg/secrets/providers/aws/secretsmanager/secretsmanager.go +++ b/pkg/secrets/providers/aws/secretsmanager/secretsmanager.go @@ -10,7 +10,7 @@ import ( "github.com/aws/aws-sdk-go-v2/service/secretsmanager/types" "github.com/tidwall/gjson" - secretsapi "kusionstack.io/kusion/pkg/apis/secrets" + "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/secrets" "kusionstack.io/kusion/pkg/secrets/providers/aws/auth" ) @@ -30,7 +30,7 @@ var _ secrets.SecretStore = &smSecretStore{} type DefaultFactory struct{} // NewSecretStore constructs a Vault based secret store with specific secret store spec. -func (p *DefaultFactory) NewSecretStore(spec secretsapi.SecretStoreSpec) (secrets.SecretStore, error) { +func (p *DefaultFactory) NewSecretStore(spec v1.SecretStoreSpec) (secrets.SecretStore, error) { providerSpec := spec.Provider if providerSpec == nil { return nil, fmt.Errorf(errMissingProviderSpec) @@ -54,7 +54,7 @@ type smSecretStore struct { } // GetSecret retrieves ref secret value from AWS Secrets Manager. -func (s *smSecretStore) GetSecret(ctx context.Context, ref secretsapi.ExternalSecretRef) ([]byte, error) { +func (s *smSecretStore) GetSecret(ctx context.Context, ref v1.ExternalSecretRef) ([]byte, error) { getSecretValueInput := s.buildGetSecretValueInput(ref) secretValueOutput, err := s.client.GetSecretValue(ctx, getSecretValueInput) var nf *types.ResourceNotFoundException @@ -81,7 +81,7 @@ func (s *smSecretStore) GetSecret(ctx context.Context, ref secretsapi.ExternalSe } // buildGetSecretValueInput constructs target GetSecretValueInput request with specific external secret ref. -func (s *smSecretStore) buildGetSecretValueInput(ref secretsapi.ExternalSecretRef) *secretsmanager.GetSecretValueInput { +func (s *smSecretStore) buildGetSecretValueInput(ref v1.ExternalSecretRef) *secretsmanager.GetSecretValueInput { version := "AWSCURRENT" if ref.Version != "" { version = ref.Version @@ -126,7 +126,7 @@ func (s *smSecretStore) convertSecretToGjson(secretValueOutput *secretsmanager.G } func init() { - secrets.Register(&DefaultFactory{}, &secretsapi.ProviderSpec{ - AWS: &secretsapi.AWSProvider{}, + secrets.Register(&DefaultFactory{}, &v1.ProviderSpec{ + AWS: &v1.AWSProvider{}, }) } diff --git a/pkg/secrets/providers/aws/secretsmanager/secretsmanager_test.go b/pkg/secrets/providers/aws/secretsmanager/secretsmanager_test.go index 20fc011a..2c8bbd1b 100644 --- a/pkg/secrets/providers/aws/secretsmanager/secretsmanager_test.go +++ b/pkg/secrets/providers/aws/secretsmanager/secretsmanager_test.go @@ -9,7 +9,7 @@ import ( "github.com/google/go-cmp/cmp" - secretsapi "kusionstack.io/kusion/pkg/apis/secrets" + "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/secrets/providers/aws/secretsmanager/fake" ) @@ -113,7 +113,7 @@ func TestGetSecret(t *testing.T) { for name, tc := range testCases { store := &smSecretStore{client: tc.client} - ref := secretsapi.ExternalSecretRef{ + ref := v1.ExternalSecretRef{ Name: tc.name, Version: tc.version, Property: tc.property, @@ -134,23 +134,23 @@ func TestGetSecret(t *testing.T) { func TestNewSecretStore(t *testing.T) { testCases := map[string]struct { - spec secretsapi.SecretStoreSpec + spec v1.SecretStoreSpec expectedErr error }{ "InvalidSecretStoreSpec": { - spec: secretsapi.SecretStoreSpec{}, + spec: v1.SecretStoreSpec{}, expectedErr: errors.New(errMissingProviderSpec), }, "InvalidProviderSpec": { - spec: secretsapi.SecretStoreSpec{ - Provider: &secretsapi.ProviderSpec{}, + spec: v1.SecretStoreSpec{ + Provider: &v1.ProviderSpec{}, }, expectedErr: errors.New(errMissingAWSProvider), }, "ValidVaultProviderSpec": { - spec: secretsapi.SecretStoreSpec{ - Provider: &secretsapi.ProviderSpec{ - AWS: &secretsapi.AWSProvider{ + spec: v1.SecretStoreSpec{ + Provider: &v1.ProviderSpec{ + AWS: &v1.AWSProvider{ Region: "us-east-1", }, }, diff --git a/pkg/secrets/providers/azure/keyvault/keyvault.go b/pkg/secrets/providers/azure/keyvault/keyvault.go index 52a49b92..023d651b 100644 --- a/pkg/secrets/providers/azure/keyvault/keyvault.go +++ b/pkg/secrets/providers/azure/keyvault/keyvault.go @@ -13,7 +13,7 @@ import ( "github.com/Azure/go-autorest/autorest/azure/auth" "github.com/tidwall/gjson" - secretsapi "kusionstack.io/kusion/pkg/apis/secrets" + "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/secrets" ) @@ -38,7 +38,7 @@ var _ secrets.SecretStore = &kvSecretStore{} type DefaultFactory struct{} // NewSecretStore constructs an Azure KeyVault based secret store with specific secret store spec. -func (p *DefaultFactory) NewSecretStore(spec secretsapi.SecretStoreSpec) (secrets.SecretStore, error) { +func (p *DefaultFactory) NewSecretStore(spec v1.SecretStoreSpec) (secrets.SecretStore, error) { providerSpec := spec.Provider if providerSpec == nil { return nil, fmt.Errorf(errMissingProviderSpec) @@ -54,7 +54,7 @@ func (p *DefaultFactory) NewSecretStore(spec secretsapi.SecretStoreSpec) (secret return &kvSecretStore{secretClient, providerSpec.Azure}, nil } -func getSecretClient(spec *secretsapi.AzureKVProvider) (SecretClient, error) { +func getSecretClient(spec *v1.AzureKVProvider) (SecretClient, error) { authorizer, err := authorizerForServicePrincipal(spec) if err != nil { return nil, err @@ -67,7 +67,7 @@ func getSecretClient(spec *secretsapi.AzureKVProvider) (SecretClient, error) { // authorizerForServicePrincipal returns a service principal based authorizer used by clients to access to Azure. // By-default it uses credentials from the environment; // See https://docs.microsoft.com/en-us/go/azure/azure-sdk-go-authorization#use-environment-based-authentication. -func authorizerForServicePrincipal(spec *secretsapi.AzureKVProvider) (autorest.Authorizer, error) { +func authorizerForServicePrincipal(spec *v1.AzureKVProvider) (autorest.Authorizer, error) { if spec.TenantID == nil { return nil, fmt.Errorf(errMissingTenant) } @@ -84,31 +84,31 @@ func authorizerForServicePrincipal(spec *secretsapi.AzureKVProvider) (autorest.A return clientCredentialsConfig.Authorizer() } -func adEndpointForEnvironmentType(t secretsapi.AzureEnvironmentType) string { +func adEndpointForEnvironmentType(t v1.AzureEnvironmentType) string { switch t { - case secretsapi.AzureEnvironmentPublicCloud: + case v1.AzureEnvironmentPublicCloud: return azure.PublicCloud.ActiveDirectoryEndpoint - case secretsapi.AzureEnvironmentChinaCloud: + case v1.AzureEnvironmentChinaCloud: return azure.ChinaCloud.ActiveDirectoryEndpoint - case secretsapi.AzureEnvironmentUSGovernmentCloud: + case v1.AzureEnvironmentUSGovernmentCloud: return azure.USGovernmentCloud.ActiveDirectoryEndpoint - case secretsapi.AzureEnvironmentGermanCloud: + case v1.AzureEnvironmentGermanCloud: return azure.GermanCloud.ActiveDirectoryEndpoint default: return azure.PublicCloud.ActiveDirectoryEndpoint } } -func kvResourceForProviderConfig(t secretsapi.AzureEnvironmentType) string { +func kvResourceForProviderConfig(t v1.AzureEnvironmentType) string { var res string switch t { - case secretsapi.AzureEnvironmentPublicCloud: + case v1.AzureEnvironmentPublicCloud: res = azure.PublicCloud.KeyVaultEndpoint - case secretsapi.AzureEnvironmentChinaCloud: + case v1.AzureEnvironmentChinaCloud: res = azure.ChinaCloud.KeyVaultEndpoint - case secretsapi.AzureEnvironmentUSGovernmentCloud: + case v1.AzureEnvironmentUSGovernmentCloud: res = azure.USGovernmentCloud.KeyVaultEndpoint - case secretsapi.AzureEnvironmentGermanCloud: + case v1.AzureEnvironmentGermanCloud: res = azure.GermanCloud.KeyVaultEndpoint default: res = azure.PublicCloud.KeyVaultEndpoint @@ -118,11 +118,11 @@ func kvResourceForProviderConfig(t secretsapi.AzureEnvironmentType) string { type kvSecretStore struct { secretClient SecretClient - provider *secretsapi.AzureKVProvider + provider *v1.AzureKVProvider } // GetSecret retrieves ref secret value from Azure KeyVault. -func (k *kvSecretStore) GetSecret(ctx context.Context, ref secretsapi.ExternalSecretRef) ([]byte, error) { +func (k *kvSecretStore) GetSecret(ctx context.Context, ref v1.ExternalSecretRef) ([]byte, error) { objectType, secretName := getObjType(ref) switch objectType { @@ -176,7 +176,7 @@ func getProperty(secret, property, key string) ([]byte, error) { return []byte(res.String()), nil } -func getObjType(ref secretsapi.ExternalSecretRef) (string, string) { +func getObjType(ref v1.ExternalSecretRef) (string, string) { objectType := defaultObjType secretName := ref.Name diff --git a/pkg/secrets/providers/azure/keyvault/keyvault_test.go b/pkg/secrets/providers/azure/keyvault/keyvault_test.go index baddc3ee..a9ef9526 100644 --- a/pkg/secrets/providers/azure/keyvault/keyvault_test.go +++ b/pkg/secrets/providers/azure/keyvault/keyvault_test.go @@ -9,7 +9,7 @@ import ( "github.com/google/go-cmp/cmp" - secretsapi "kusionstack.io/kusion/pkg/apis/secrets" + "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/secrets/providers/azure/keyvault/fake" ) @@ -73,7 +73,7 @@ func TestGetSecret(t *testing.T) { }, } - provider := &secretsapi.AzureKVProvider{ + provider := &v1.AzureKVProvider{ VaultURL: &fakeVaultURL, TenantID: &fakeTenantID, } @@ -83,7 +83,7 @@ func TestGetSecret(t *testing.T) { secretClient: tc.client, provider: provider, } - ref := secretsapi.ExternalSecretRef{ + ref := v1.ExternalSecretRef{ Name: tc.name, Property: tc.property, } @@ -100,24 +100,24 @@ func TestGetSecret(t *testing.T) { func TestNewSecretStore(t *testing.T) { testCases := map[string]struct { - spec secretsapi.SecretStoreSpec + spec v1.SecretStoreSpec initEnv bool expectedErr error }{ "InvalidSecretStoreSpec": { - spec: secretsapi.SecretStoreSpec{}, + spec: v1.SecretStoreSpec{}, expectedErr: errors.New(errMissingProviderSpec), }, "InvalidProviderSpec": { - spec: secretsapi.SecretStoreSpec{ - Provider: &secretsapi.ProviderSpec{}, + spec: v1.SecretStoreSpec{ + Provider: &v1.ProviderSpec{}, }, expectedErr: errors.New(errMissingAzureProvider), }, "InvalidAzureKVProviderSpec": { - spec: secretsapi.SecretStoreSpec{ - Provider: &secretsapi.ProviderSpec{ - Azure: &secretsapi.AzureKVProvider{ + spec: v1.SecretStoreSpec{ + Provider: &v1.ProviderSpec{ + Azure: &v1.AzureKVProvider{ VaultURL: &fakeVaultURL, }, }, @@ -125,9 +125,9 @@ func TestNewSecretStore(t *testing.T) { expectedErr: errors.New(errMissingTenant), }, "NoClientIDSecretEnvFound": { - spec: secretsapi.SecretStoreSpec{ - Provider: &secretsapi.ProviderSpec{ - Azure: &secretsapi.AzureKVProvider{ + spec: v1.SecretStoreSpec{ + Provider: &v1.ProviderSpec{ + Azure: &v1.AzureKVProvider{ VaultURL: &fakeVaultURL, TenantID: &fakeTenantID, }, @@ -136,9 +136,9 @@ func TestNewSecretStore(t *testing.T) { expectedErr: errors.New(errMissingClientIDSecret), }, "ValidVaultProviderSpec": { - spec: secretsapi.SecretStoreSpec{ - Provider: &secretsapi.ProviderSpec{ - Azure: &secretsapi.AzureKVProvider{ + spec: v1.SecretStoreSpec{ + Provider: &v1.ProviderSpec{ + Azure: &v1.AzureKVProvider{ VaultURL: &fakeVaultURL, TenantID: &fakeTenantID, }, diff --git a/pkg/secrets/providers/hashivault/vault.go b/pkg/secrets/providers/hashivault/vault.go index 1dc6fcb1..79a5ade2 100644 --- a/pkg/secrets/providers/hashivault/vault.go +++ b/pkg/secrets/providers/hashivault/vault.go @@ -13,7 +13,7 @@ import ( vault "github.com/hashicorp/vault/api" "github.com/tidwall/gjson" - secretsapi "kusionstack.io/kusion/pkg/apis/secrets" + "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/secrets" ) @@ -41,7 +41,7 @@ func (p *DefaultFactory) Type() string { } // NewSecretStore constructs a Vault based secret store with specific secret store spec. -func (p *DefaultFactory) NewSecretStore(spec secretsapi.SecretStoreSpec) (secrets.SecretStore, error) { +func (p *DefaultFactory) NewSecretStore(spec v1.SecretStoreSpec) (secrets.SecretStore, error) { providerSpec := spec.Provider if providerSpec == nil || providerSpec.Vault == nil { return nil, errors.New(errInvalidVaultSecretStore) @@ -92,12 +92,12 @@ func getVaultToken() string { } type vaultSecretStore struct { - provider *secretsapi.VaultProvider + provider *v1.VaultProvider logical Logical } // GetSecret retrieves ref secret value from Vault server. -func (v *vaultSecretStore) GetSecret(ctx context.Context, ref secretsapi.ExternalSecretRef) ([]byte, error) { +func (v *vaultSecretStore) GetSecret(ctx context.Context, ref v1.ExternalSecretRef) ([]byte, error) { secretData, err := v.readSecret(ctx, ref.Name, ref.Version) if err != nil { return nil, err @@ -141,7 +141,7 @@ func (v *vaultSecretStore) readSecret(ctx context.Context, path, version string) return map[string]interface{}{}, nil } secretData := secret.Data - if v.provider.Version == secretsapi.VaultKVStoreV2 { + if v.provider.Version == v1.VaultKVStoreV2 { // Vault KV2 has data embedded within sub-field // Ref: https://developer.hashicorp.com/vault/api-docs/secret/kv/kv-v2#read-secret-version embeddedData, ok := secretData["data"] @@ -172,20 +172,20 @@ func (v *vaultSecretStore) buildPath(path string) string { if strings.HasPrefix(out, prefixToCut) { _, out, _ = strings.Cut(out, prefixToCut) // if data succeeds mountPath on v2 store, we should remove it as well - if strings.HasPrefix(out, "data/") && v.provider.Version == secretsapi.VaultKVStoreV2 { + if strings.HasPrefix(out, "data/") && v.provider.Version == v1.VaultKVStoreV2 { _, out, _ = strings.Cut(out, "data/") } } buildPath := strings.Split(out, "/") buildMount := strings.Split(*mountPath, "/") - if v.provider.Version == secretsapi.VaultKVStoreV2 { + if v.provider.Version == v1.VaultKVStoreV2 { buildMount = append(buildMount, "data") } buildMount = append(buildMount, buildPath...) out = strings.Join(buildMount, "/") return out } - if !strings.Contains(out, "/data/") && v.provider.Version == secretsapi.VaultKVStoreV2 { + if !strings.Contains(out, "/data/") && v.provider.Version == v1.VaultKVStoreV2 { buildPath := strings.Split(out, "/") buildMount := []string{buildPath[0], "data"} buildMount = append(buildMount, buildPath[1:]...) @@ -226,7 +226,7 @@ func getTypedKey(data map[string]interface{}, key string) ([]byte, error) { } func init() { - secrets.Register(&DefaultFactory{}, &secretsapi.ProviderSpec{ - Vault: &secretsapi.VaultProvider{}, + secrets.Register(&DefaultFactory{}, &v1.ProviderSpec{ + Vault: &v1.VaultProvider{}, }) } diff --git a/pkg/secrets/providers/hashivault/vault_test.go b/pkg/secrets/providers/hashivault/vault_test.go index 5c7e9917..7b086421 100644 --- a/pkg/secrets/providers/hashivault/vault_test.go +++ b/pkg/secrets/providers/hashivault/vault_test.go @@ -10,23 +10,23 @@ import ( "github.com/google/go-cmp/cmp" - secretsapi "kusionstack.io/kusion/pkg/apis/secrets" + "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/secrets/providers/hashivault/fake" ) var mountPath = "secret" -func makeValidVaultSecretStore(v secretsapi.VaultKVStoreVersion) *vaultSecretStore { +func makeValidVaultSecretStore(v v1.VaultKVStoreVersion) *vaultSecretStore { return &vaultSecretStore{ - provider: &secretsapi.VaultProvider{ + provider: &v1.VaultProvider{ Path: &mountPath, Version: v, }, } } -func makeExternalSecretRef(path, property, version string) secretsapi.ExternalSecretRef { - return secretsapi.ExternalSecretRef{ +func makeExternalSecretRef(path, property, version string) v1.ExternalSecretRef { + return v1.ExternalSecretRef{ Name: path, Property: property, Version: version, @@ -65,7 +65,7 @@ func TestGetSecret(t *testing.T) { }, } testCases := map[string]struct { - provider *secretsapi.VaultProvider + provider *v1.VaultProvider logical Logical path string property string @@ -74,7 +74,7 @@ func TestGetSecret(t *testing.T) { expectErr error }{ "V1_ReadSecret": { - provider: makeValidVaultSecretStore(secretsapi.VaultKVStoreV1).provider, + provider: makeValidVaultSecretStore(v1.VaultKVStoreV1).provider, logical: &fake.Logical{ ReadWithDataWithContextFn: fake.NewReadWithContextFn(secretData, nil), }, @@ -84,7 +84,7 @@ func TestGetSecret(t *testing.T) { expectErr: nil, }, "V1_ReadSecret_NoProperty": { - provider: makeValidVaultSecretStore(secretsapi.VaultKVStoreV1).provider, + provider: makeValidVaultSecretStore(v1.VaultKVStoreV1).provider, logical: &fake.Logical{ ReadWithDataWithContextFn: fake.NewReadWithContextFn(secretData, nil), }, @@ -93,7 +93,7 @@ func TestGetSecret(t *testing.T) { expectErr: nil, }, "V1_ReadSecret_NoProperty_NilValue": { - provider: makeValidVaultSecretStore(secretsapi.VaultKVStoreV1).provider, + provider: makeValidVaultSecretStore(v1.VaultKVStoreV1).provider, logical: &fake.Logical{ ReadWithDataWithContextFn: fake.NewReadWithContextFn(secretDataWithNilValue, nil), }, @@ -102,7 +102,7 @@ func TestGetSecret(t *testing.T) { expectErr: nil, }, "V1_ReadSecret_NestedValue": { - provider: makeValidVaultSecretStore(secretsapi.VaultKVStoreV1).provider, + provider: makeValidVaultSecretStore(v1.VaultKVStoreV1).provider, logical: &fake.Logical{ ReadWithDataWithContextFn: fake.NewReadWithContextFn(secretDataWithNestedValue, nil), }, @@ -112,7 +112,7 @@ func TestGetSecret(t *testing.T) { expectErr: nil, }, "V1_ReadSecret_NestedValue_NestedProperty": { - provider: makeValidVaultSecretStore(secretsapi.VaultKVStoreV1).provider, + provider: makeValidVaultSecretStore(v1.VaultKVStoreV1).provider, logical: &fake.Logical{ ReadWithDataWithContextFn: fake.NewReadWithContextFn(secretDataWithNestedValue, nil), }, @@ -122,7 +122,7 @@ func TestGetSecret(t *testing.T) { expectErr: nil, }, "V1_ReadSecret_SliceValue": { - provider: makeValidVaultSecretStore(secretsapi.VaultKVStoreV1).provider, + provider: makeValidVaultSecretStore(v1.VaultKVStoreV1).provider, logical: &fake.Logical{ ReadWithDataWithContextFn: fake.NewReadWithContextFn(secretDataWithNestedValue, nil), }, @@ -132,7 +132,7 @@ func TestGetSecret(t *testing.T) { expectErr: nil, }, "V1_ReadSecret_JsonNumber": { - provider: makeValidVaultSecretStore(secretsapi.VaultKVStoreV1).provider, + provider: makeValidVaultSecretStore(v1.VaultKVStoreV1).provider, logical: &fake.Logical{ ReadWithDataWithContextFn: fake.NewReadWithContextFn(secretDataWithNestedValue, nil), }, @@ -142,7 +142,7 @@ func TestGetSecret(t *testing.T) { expectErr: nil, }, "V1_ReadSecret_NilData": { - provider: makeValidVaultSecretStore(secretsapi.VaultKVStoreV1).provider, + provider: makeValidVaultSecretStore(v1.VaultKVStoreV1).provider, logical: &fake.Logical{ ReadWithDataWithContextFn: fake.NewReadWithContextFn(nil, nil), }, @@ -151,7 +151,7 @@ func TestGetSecret(t *testing.T) { expectErr: nil, }, "V2_ReadSecret": { - provider: makeValidVaultSecretStore(secretsapi.VaultKVStoreV2).provider, + provider: makeValidVaultSecretStore(v1.VaultKVStoreV2).provider, logical: &fake.Logical{ ReadWithDataWithContextFn: fake.NewReadWithContextFn(secretNestedData, nil), }, @@ -161,7 +161,7 @@ func TestGetSecret(t *testing.T) { expectErr: nil, }, "V2_ReadSecret_WithVersion": { - provider: makeValidVaultSecretStore(secretsapi.VaultKVStoreV2).provider, + provider: makeValidVaultSecretStore(v1.VaultKVStoreV2).provider, logical: &fake.Logical{ ReadWithDataWithContextFn: fake.NewReadWithContextFn(secretNestedData, nil), }, @@ -172,7 +172,7 @@ func TestGetSecret(t *testing.T) { expectErr: nil, }, "V2_ReadSecret_ErrFormat": { - provider: makeValidVaultSecretStore(secretsapi.VaultKVStoreV2).provider, + provider: makeValidVaultSecretStore(v1.VaultKVStoreV2).provider, logical: &fake.Logical{ ReadWithDataWithContextFn: fake.NewReadWithContextFn(secretData, nil), }, @@ -199,15 +199,15 @@ func TestGetSecret(t *testing.T) { } func TestBuildPath(t *testing.T) { - storeV2 := makeValidVaultSecretStore(secretsapi.VaultKVStoreV2) + storeV2 := makeValidVaultSecretStore(v1.VaultKVStoreV2) otherMountPath := "secret/path" storeV2.provider.Path = &otherMountPath - storeV2NoPath := makeValidVaultSecretStore(secretsapi.VaultKVStoreV2) + storeV2NoPath := makeValidVaultSecretStore(v1.VaultKVStoreV2) storeV2NoPath.provider.Path = nil - storeV1 := makeValidVaultSecretStore(secretsapi.VaultKVStoreV1) + storeV1 := makeValidVaultSecretStore(v1.VaultKVStoreV1) storeV1.provider.Path = &otherMountPath - storeV1NoPath := makeValidVaultSecretStore(secretsapi.VaultKVStoreV1) + storeV1NoPath := makeValidVaultSecretStore(v1.VaultKVStoreV1) storeV1NoPath.provider.Path = nil testCases := map[string]struct { @@ -262,23 +262,23 @@ func TestBuildPath(t *testing.T) { func TestNewSecretStore(t *testing.T) { testCases := map[string]struct { - spec secretsapi.SecretStoreSpec + spec v1.SecretStoreSpec expectedErr error }{ "InvalidSecretStoreSpec": { - spec: secretsapi.SecretStoreSpec{}, + spec: v1.SecretStoreSpec{}, expectedErr: errors.New(errInvalidVaultSecretStore), }, "InvalidProviderSpec": { - spec: secretsapi.SecretStoreSpec{ - Provider: &secretsapi.ProviderSpec{}, + spec: v1.SecretStoreSpec{ + Provider: &v1.ProviderSpec{}, }, expectedErr: errors.New(errInvalidVaultSecretStore), }, "ValidVaultProviderSpec": { - spec: secretsapi.SecretStoreSpec{ - Provider: &secretsapi.ProviderSpec{ - Vault: &secretsapi.VaultProvider{ + spec: v1.SecretStoreSpec{ + Provider: &v1.ProviderSpec{ + Vault: &v1.VaultProvider{ Server: "https://127.0.0.1:8200", }, }, @@ -286,9 +286,9 @@ func TestNewSecretStore(t *testing.T) { expectedErr: nil, }, "ValidVaultProviderSpec_WithToken": { - spec: secretsapi.SecretStoreSpec{ - Provider: &secretsapi.ProviderSpec{ - Vault: &secretsapi.VaultProvider{ + spec: v1.SecretStoreSpec{ + Provider: &v1.ProviderSpec{ + Vault: &v1.VaultProvider{ Server: "https://127.0.0.1:8200", }, }, diff --git a/pkg/secrets/providers_test.go b/pkg/secrets/providers_test.go index a88c52db..5fdffe91 100644 --- a/pkg/secrets/providers_test.go +++ b/pkg/secrets/providers_test.go @@ -6,14 +6,14 @@ import ( "github.com/stretchr/testify/assert" - "kusionstack.io/kusion/pkg/apis/secrets" + "kusionstack.io/kusion/pkg/apis/core/v1" ) // FakeSecretStore is the fake implementation of SecretStore. type FakeSecretStore struct{} // Fake implementation of SecretStore.GetSecret. -func (fss *FakeSecretStore) GetSecret(_ context.Context, _ secrets.ExternalSecretRef) ([]byte, error) { +func (fss *FakeSecretStore) GetSecret(_ context.Context, _ v1.ExternalSecretRef) ([]byte, error) { return []byte("NOOP"), nil } @@ -21,7 +21,7 @@ func (fss *FakeSecretStore) GetSecret(_ context.Context, _ secrets.ExternalSecre type FakeSecretStoreFactory struct{} // Fake implementation of SecretStoreFactory.NewSecretStore. -func (fsf *FakeSecretStoreFactory) NewSecretStore(_ secrets.SecretStoreSpec) (SecretStore, error) { +func (fsf *FakeSecretStoreFactory) NewSecretStore(_ v1.SecretStoreSpec) (SecretStore, error) { return &FakeSecretStore{}, nil } @@ -31,20 +31,20 @@ func TestRegister(t *testing.T) { providerName string shouldPanic bool expExists bool - spec *secrets.ProviderSpec + spec *v1.ProviderSpec }{ { name: "should panic when given an invalid provider spec", shouldPanic: true, - spec: &secrets.ProviderSpec{}, + spec: &v1.ProviderSpec{}, }, { name: "should register a valid provider", providerName: "aws", shouldPanic: false, expExists: true, - spec: &secrets.ProviderSpec{ - AWS: &secrets.AWSProvider{}, + spec: &v1.ProviderSpec{ + AWS: &v1.AWSProvider{}, }, }, }