Skip to content

Commit

Permalink
feat: update workspace type add secret store config
Browse files Browse the repository at this point in the history
  • Loading branch information
adohe committed Dec 26, 2023
1 parent 96d1a1d commit 318822b
Show file tree
Hide file tree
Showing 2 changed files with 267 additions and 12 deletions.
82 changes: 70 additions & 12 deletions pkg/workspace/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"errors"
"fmt"

utilerrors "k8s.io/apimachinery/pkg/util/errors"

"kusionstack.io/kusion/pkg/apis/core/v1"
)

Expand Down Expand Up @@ -45,6 +47,10 @@ var (
ErrMultiSecretStoreProviders = errors.New("may not specify more than 1 secret store provider")
ErrEmptyAWSRegion = errors.New("region must be provided when using AWS Secrets Manager")
ErrEmptyVaultServer = errors.New("server address must be provided when using Hashicorp Vault")
ErrEmptyVaultUrl = errors.New("vault url must be provided when using Azure KeyVault")

Check failure on line 50 in pkg/workspace/validation.go

View workflow job for this annotation

GitHub Actions / Golang Lint

ST1003: var ErrEmptyVaultUrl should be ErrEmptyVaultURL (stylecheck)
ErrEmptyTenantID = errors.New("azure tenant id must be provided when using Azure KeyVault")
ErrEmptyAlicloudRegion = errors.New("region must be provided when using Alicloud Secrets Manager")
ErrMissingProviderType = errors.New("must specify a provider type")
)

// ValidateWorkspace is used to validate the workspace get or set in the storage, and does not validate the
Expand All @@ -69,8 +75,8 @@ func ValidateWorkspace(ws *v1.Workspace) error {
}
}
if ws.SecretStore != nil {
if err := ValidateSecretStoreConfig(ws.SecretStore); err != nil {
return err
if allErrs := ValidateSecretStoreConfig(ws.SecretStore); allErrs != nil {
return utilerrors.NewAggregate(allErrs)
}
}
return nil
Expand Down Expand Up @@ -331,28 +337,80 @@ func validateWholeGenericObjectStorageConfig(config *v1.GenericObjectStorageConf
}

// ValidateSecretStoreConfig tests that the specified SecretStoreSpec has valid data.
func ValidateSecretStoreConfig(spec *v1.SecretStoreSpec) error {
func ValidateSecretStoreConfig(spec *v1.SecretStoreSpec) []error {
if spec.Provider == nil {
return ErrMissingProvider
return []error{ErrMissingProvider}
}

numProviders := 0
var allErrs []error
if spec.Provider.AWS != nil {
numProviders++
if len(spec.Provider.AWS.Region) == 0 {
return ErrEmptyAWSRegion
}
allErrs = append(allErrs, validateAWSSecretStore(spec.Provider.AWS)...)
}
if spec.Provider.Vault != nil {
if numProviders > 0 {
return ErrMultiSecretStoreProviders
allErrs = append(allErrs, ErrMultiSecretStoreProviders)
} else {
numProviders++
if len(spec.Provider.Vault.Server) == 0 {
return ErrEmptyVaultServer
}
allErrs = append(allErrs, validateHashiVaultSecretStore(spec.Provider.Vault)...)
}
}
if spec.Provider.Azure != nil {
if numProviders > 0 {
allErrs = append(allErrs, ErrMultiSecretStoreProviders)
} else {
numProviders++
allErrs = append(allErrs, validateAzureKeyVaultSecretStore(spec.Provider.Azure)...)
}
}
if spec.Provider.Alicloud != nil {
if numProviders > 0 {
allErrs = append(allErrs, ErrMultiSecretStoreProviders)
} else {
numProviders++
allErrs = append(allErrs, validateAlicloudSecretStore(spec.Provider.Alicloud)...)
}
}

return nil
if numProviders == 0 {
allErrs = append(allErrs, ErrMissingProviderType)
}

return allErrs
}

func validateAWSSecretStore(ss *v1.AWSProvider) []error {
var allErrs []error
if len(ss.Region) == 0 {
allErrs = append(allErrs, ErrEmptyAWSRegion)
}
return allErrs
}

func validateHashiVaultSecretStore(vault *v1.VaultProvider) []error {
var allErrs []error
if len(vault.Server) == 0 {
allErrs = append(allErrs, ErrEmptyVaultServer)
}
return allErrs
}

func validateAzureKeyVaultSecretStore(azureKv *v1.AzureKVProvider) []error {
var allErrs []error
if azureKv.VaultURL == nil || len(*azureKv.VaultURL) == 0 {
allErrs = append(allErrs, ErrEmptyVaultUrl)
}
if azureKv.TenantID == nil || len(*azureKv.TenantID) == 0 {
allErrs = append(allErrs, ErrEmptyTenantID)
}
return allErrs
}

func validateAlicloudSecretStore(ac *v1.AlicloudProvider) []error {
var allErrs []error
if len(ac.Region) == 0 {
allErrs = append(allErrs, ErrEmptyAlicloudRegion)
}
return allErrs
}
197 changes: 197 additions & 0 deletions pkg/workspace/validation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -665,3 +665,200 @@ func TestValidateWholeS3Config(t *testing.T) {
})
}
}

func TestValidateAWSSecretStore(t *testing.T) {
type args struct {
ss *v1.AWSProvider
}
tests := []struct {
name string
args args
want []error
}{
{
name: "valid AWS provider spec",
args: args{
ss: &v1.AWSProvider{
Region: "eu-west-2",
},
},
want: nil,
},
{
name: "invalid AWS provider spec",
args: args{
ss: &v1.AWSProvider{},
},
want: []error{ErrEmptyAWSRegion},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equalf(t, tt.want, validateAWSSecretStore(tt.args.ss), "validateAWSSecretStore(%v)", tt.args.ss)
})
}
}

func TestValidateHashiVaultSecretStore(t *testing.T) {
type args struct {
vault *v1.VaultProvider
}
tests := []struct {
name string
args args
want []error
}{
{
name: "valid Hashi Vault provider spec",
args: args{
vault: &v1.VaultProvider{
Server: "https://vault.example.com:8200",
},
},
want: nil,
},
{
name: "invalid Hashi Vault provider spec",
args: args{
vault: &v1.VaultProvider{},
},
want: []error{ErrEmptyVaultServer},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equalf(t, tt.want, validateHashiVaultSecretStore(tt.args.vault), "validateHashiVaultSecretStore(%v)", tt.args.vault)
})
}
}

func TestValidateAzureKeyVaultSecretStore(t *testing.T) {
type args struct {
azureKv *v1.AzureKVProvider
}
var vaultUrl = "https://local.vault.url"

Check failure on line 739 in pkg/workspace/validation_test.go

View workflow job for this annotation

GitHub Actions / Golang Lint

File is not `gofumpt`-ed (gofumpt)
var tenantID = "my-tenant-id"
tests := []struct {
name string
args args
want []error
}{
{
name: "valid Azure KV provider spec",
args: args{
azureKv: &v1.AzureKVProvider{
VaultURL: &vaultUrl,
TenantID: &tenantID,
},
},
want: nil,
},
{
name: "invalid Azure KV provider spec",
args: args{
azureKv: &v1.AzureKVProvider{},
},
want: []error{ErrEmptyVaultUrl, ErrEmptyTenantID},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equalf(t, tt.want, validateAzureKeyVaultSecretStore(tt.args.azureKv), "validateAzureKeyVaultSecretStore(%v)", tt.args.azureKv)
})
}
}

func TestValidateAlicloudSecretStore(t *testing.T) {
type args struct {
ac *v1.AlicloudProvider
}
tests := []struct {
name string
args args
want []error
}{
{
name: "valid Alicloud provider spec",
args: args{
ac: &v1.AlicloudProvider{
Region: "sh",
},
},
want: nil,
},
{
name: "invalid Alicloud provider spec",
args: args{
ac: &v1.AlicloudProvider{},
},
want: []error{ErrEmptyAlicloudRegion},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equalf(t, tt.want, validateAlicloudSecretStore(tt.args.ac), "validateAlicloudSecretStore(%v)", tt.args.ac)
})
}
}

func TestValidateSecretStoreConfig(t *testing.T) {
type args struct {
spec *v1.SecretStoreSpec
}
tests := []struct {
name string
args args
want []error
}{
{
name: "missing provider spec",
args: args{
spec: &v1.SecretStoreSpec{},
},
want: []error{ErrMissingProvider},
},
{
name: "missing provider type",
args: args{
spec: &v1.SecretStoreSpec{
Provider: &v1.ProviderSpec{},
},
},
want: []error{ErrMissingProviderType},
},
{
name: "multi secret store providers",
args: args{
spec: &v1.SecretStoreSpec{
Provider: &v1.ProviderSpec{
AWS: &v1.AWSProvider{
Region: "us-east-1",
},
Vault: &v1.VaultProvider{
Server: "https://vault.example.com:8200",
},
},
},
},
want: []error{ErrMultiSecretStoreProviders},
},
{
name: "valid secret store spec",
args: args{
spec: &v1.SecretStoreSpec{
Provider: &v1.ProviderSpec{
AWS: &v1.AWSProvider{
Region: "us-east-1",
},
},
},
},
want: nil,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equalf(t, tt.want, ValidateSecretStoreConfig(tt.args.spec), "validateAlicloudSecretStore(%v)", tt.args.spec)
})
}
}

0 comments on commit 318822b

Please sign in to comment.