From 176919c4cfb0dc7ecc4987442c6d70b676cea156 Mon Sep 17 00:00:00 2001 From: Anish Ramasekar Date: Wed, 26 Oct 2022 21:18:01 +0000 Subject: [PATCH 1/2] [KMSv2]: add validation for duplicate kms config name Signed-off-by: Anish Ramasekar --- .../pkg/apis/config/validation/validation.go | 31 ++- .../apis/config/validation/validation_test.go | 203 +++++++++++++++++- 2 files changed, 220 insertions(+), 14 deletions(-) diff --git a/staging/src/k8s.io/apiserver/pkg/apis/config/validation/validation.go b/staging/src/k8s.io/apiserver/pkg/apis/config/validation/validation.go index fc30efa92fa..b453dcfa02b 100644 --- a/staging/src/k8s.io/apiserver/pkg/apis/config/validation/validation.go +++ b/staging/src/k8s.io/apiserver/pkg/apis/config/validation/validation.go @@ -23,6 +23,7 @@ import ( "net/url" "strings" + "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/apiserver/pkg/apis/config" ) @@ -40,6 +41,7 @@ const ( nonZeroErrFmt = "%s should be a positive value, or negative to disable" encryptionConfigNilErr = "EncryptionConfiguration can't be nil" invalidKMSConfigNameErrFmt = "invalid KMS provider name %s, must not contain ':'" + duplicateKMSConfigNameErrFmt = "duplicate KMS provider name %s, names must be unique" ) var ( @@ -66,6 +68,8 @@ func ValidateEncryptionConfiguration(c *config.EncryptionConfiguration) field.Er return allErrs } + // kmsProviderNames is used to track config names to ensure they are unique. + kmsProviderNames := sets.NewString() for i, conf := range c.Resources { r := root.Index(i).Child("resources") p := root.Index(i).Child("providers") @@ -84,7 +88,8 @@ func ValidateEncryptionConfiguration(c *config.EncryptionConfiguration) field.Er switch { case provider.KMS != nil: - allErrs = append(allErrs, validateKMSConfiguration(provider.KMS, path.Child("kms"))...) + allErrs = append(allErrs, validateKMSConfiguration(provider.KMS, path.Child("kms"), kmsProviderNames)...) + kmsProviderNames.Insert(provider.KMS.Name) case provider.AESGCM != nil: allErrs = append(allErrs, validateKeys(provider.AESGCM.Keys, path.Child("aesgcm").Child("keys"), aesKeySizes)...) case provider.AESCBC != nil: @@ -98,7 +103,7 @@ func ValidateEncryptionConfiguration(c *config.EncryptionConfiguration) field.Er return allErrs } -func validateSingleProvider(provider config.ProviderConfiguration, filedPath *field.Path) field.ErrorList { +func validateSingleProvider(provider config.ProviderConfiguration, fieldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} found := 0 @@ -119,11 +124,11 @@ func validateSingleProvider(provider config.ProviderConfiguration, filedPath *fi } if found == 0 { - return append(allErrs, field.Invalid(filedPath, provider, "provider does not contain any of the expected providers: KMS, AESGCM, AESCBC, Secretbox, Identity")) + return append(allErrs, field.Invalid(fieldPath, provider, "provider does not contain any of the expected providers: KMS, AESGCM, AESCBC, Secretbox, Identity")) } if found > 1 { - return append(allErrs, field.Invalid(filedPath, provider, moreThanOneElementErr)) + return append(allErrs, field.Invalid(fieldPath, provider, moreThanOneElementErr)) } return allErrs @@ -177,10 +182,10 @@ func validateKey(key config.Key, fieldPath *field.Path, expectedLen []int) field return allErrs } -func validateKMSConfiguration(c *config.KMSConfiguration, fieldPath *field.Path) field.ErrorList { +func validateKMSConfiguration(c *config.KMSConfiguration, fieldPath *field.Path, kmsProviderNames sets.String) field.ErrorList { allErrs := field.ErrorList{} - allErrs = append(allErrs, validateKMSConfigName(c, fieldPath.Child("name"))...) + allErrs = append(allErrs, validateKMSConfigName(c, fieldPath.Child("name"), kmsProviderNames)...) allErrs = append(allErrs, validateKMSTimeout(c, fieldPath.Child("timeout"))...) allErrs = append(allErrs, validateKMSEndpoint(c, fieldPath.Child("endpoint"))...) allErrs = append(allErrs, validateKMSCacheSize(c, fieldPath.Child("cachesize"))...) @@ -233,14 +238,22 @@ func validateKMSAPIVersion(c *config.KMSConfiguration, fieldPath *field.Path) fi return allErrs } -func validateKMSConfigName(c *config.KMSConfiguration, fieldPath *field.Path) field.ErrorList { +func validateKMSConfigName(c *config.KMSConfiguration, fieldPath *field.Path, kmsProviderNames sets.String) field.ErrorList { allErrs := field.ErrorList{} if c.Name == "" { allErrs = append(allErrs, field.Required(fieldPath, fmt.Sprintf(mandatoryFieldErrFmt, "name", "provider"))) } - if c.APIVersion != "v1" && strings.Contains(c.Name, ":") { - allErrs = append(allErrs, field.Invalid(fieldPath, c.Name, fmt.Sprintf(invalidKMSConfigNameErrFmt, c.Name))) + if c.APIVersion != "v1" { + // kms v2 providers are not allowed to have a ":" in their name + if strings.Contains(c.Name, ":") { + allErrs = append(allErrs, field.Invalid(fieldPath, c.Name, fmt.Sprintf(invalidKMSConfigNameErrFmt, c.Name))) + } + // kms v2 providers name should be unique across all kms providers (v1 and v2) + // TODO(aramase): make this check for v1 and v2 (all kms versions) once https://github.com/kubernetes/kubernetes/pull/113529 is merged + if kmsProviderNames.Has(c.Name) { + allErrs = append(allErrs, field.Invalid(fieldPath, c.Name, fmt.Sprintf(duplicateKMSConfigNameErrFmt, c.Name))) + } } return allErrs diff --git a/staging/src/k8s.io/apiserver/pkg/apis/config/validation/validation_test.go b/staging/src/k8s.io/apiserver/pkg/apis/config/validation/validation_test.go index 85087c4feef..01881004d4e 100644 --- a/staging/src/k8s.io/apiserver/pkg/apis/config/validation/validation_test.go +++ b/staging/src/k8s.io/apiserver/pkg/apis/config/validation/validation_test.go @@ -23,12 +23,14 @@ import ( "github.com/google/go-cmp/cmp" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/apiserver/pkg/apis/config" ) func TestStructure(t *testing.T) { firstResourcePath := root.Index(0) + cacheSize := int32(1) testCases := []struct { desc string in *config.EncryptionConfiguration @@ -161,13 +163,190 @@ func TestStructure(t *testing.T) { }, want: field.ErrorList{}, }, + { + desc: "duplicate kms v2 config name with kms v1 config", + in: &config.EncryptionConfiguration{ + Resources: []config.ResourceConfiguration{ + { + Resources: []string{"secrets"}, + Providers: []config.ProviderConfiguration{ + { + KMS: &config.KMSConfiguration{ + Name: "foo", + Endpoint: "unix:///tmp/kms-provider-1.socket", + Timeout: &metav1.Duration{Duration: 3 * time.Second}, + CacheSize: &cacheSize, + APIVersion: "v1", + }, + }, + { + KMS: &config.KMSConfiguration{ + Name: "foo", + Endpoint: "unix:///tmp/kms-provider-2.socket", + Timeout: &metav1.Duration{Duration: 3 * time.Second}, + CacheSize: &cacheSize, + APIVersion: "v2", + }, + }, + }, + }, + }, + }, + want: field.ErrorList{ + field.Invalid(firstResourcePath.Child("providers").Index(1).Child("kms").Child("name"), + "foo", fmt.Sprintf(duplicateKMSConfigNameErrFmt, "foo")), + }, + }, + { + desc: "duplicate kms v2 config names", + in: &config.EncryptionConfiguration{ + Resources: []config.ResourceConfiguration{ + { + Resources: []string{"secrets"}, + Providers: []config.ProviderConfiguration{ + { + KMS: &config.KMSConfiguration{ + Name: "foo", + Endpoint: "unix:///tmp/kms-provider-1.socket", + Timeout: &metav1.Duration{Duration: 3 * time.Second}, + CacheSize: &cacheSize, + APIVersion: "v2", + }, + }, + { + KMS: &config.KMSConfiguration{ + Name: "foo", + Endpoint: "unix:///tmp/kms-provider-2.socket", + Timeout: &metav1.Duration{Duration: 3 * time.Second}, + CacheSize: &cacheSize, + APIVersion: "v2", + }, + }, + }, + }, + }, + }, + want: field.ErrorList{ + field.Invalid(firstResourcePath.Child("providers").Index(1).Child("kms").Child("name"), + "foo", fmt.Sprintf(duplicateKMSConfigNameErrFmt, "foo")), + }, + }, + { + desc: "duplicate kms v2 config name across providers", + in: &config.EncryptionConfiguration{ + Resources: []config.ResourceConfiguration{ + { + Resources: []string{"secrets"}, + Providers: []config.ProviderConfiguration{ + { + KMS: &config.KMSConfiguration{ + Name: "foo", + Endpoint: "unix:///tmp/kms-provider-1.socket", + Timeout: &metav1.Duration{Duration: 3 * time.Second}, + CacheSize: &cacheSize, + APIVersion: "v2", + }, + }, + }, + }, + { + Resources: []string{"secrets"}, + Providers: []config.ProviderConfiguration{ + { + KMS: &config.KMSConfiguration{ + Name: "foo", + Endpoint: "unix:///tmp/kms-provider-2.socket", + Timeout: &metav1.Duration{Duration: 3 * time.Second}, + CacheSize: &cacheSize, + APIVersion: "v2", + }, + }, + }, + }, + }, + }, + want: field.ErrorList{ + field.Invalid(root.Index(1).Child("providers").Index(0).Child("kms").Child("name"), + "foo", fmt.Sprintf(duplicateKMSConfigNameErrFmt, "foo")), + }, + }, + { + desc: "duplicate kms config name with v1 and v2 across providers", + in: &config.EncryptionConfiguration{ + Resources: []config.ResourceConfiguration{ + { + Resources: []string{"secrets"}, + Providers: []config.ProviderConfiguration{ + { + KMS: &config.KMSConfiguration{ + Name: "foo", + Endpoint: "unix:///tmp/kms-provider-1.socket", + Timeout: &metav1.Duration{Duration: 3 * time.Second}, + CacheSize: &cacheSize, + APIVersion: "v1", + }, + }, + }, + }, + { + Resources: []string{"secrets"}, + Providers: []config.ProviderConfiguration{ + { + KMS: &config.KMSConfiguration{ + Name: "foo", + Endpoint: "unix:///tmp/kms-provider-2.socket", + Timeout: &metav1.Duration{Duration: 3 * time.Second}, + CacheSize: &cacheSize, + APIVersion: "v2", + }, + }, + }, + }, + }, + }, + want: field.ErrorList{ + field.Invalid(root.Index(1).Child("providers").Index(0).Child("kms").Child("name"), + "foo", fmt.Sprintf(duplicateKMSConfigNameErrFmt, "foo")), + }, + }, + { + desc: "duplicate kms v1 config names shouldn't error", + in: &config.EncryptionConfiguration{ + Resources: []config.ResourceConfiguration{ + { + Resources: []string{"secrets"}, + Providers: []config.ProviderConfiguration{ + { + KMS: &config.KMSConfiguration{ + Name: "foo", + Endpoint: "unix:///tmp/kms-provider-1.socket", + Timeout: &metav1.Duration{Duration: 3 * time.Second}, + CacheSize: &cacheSize, + APIVersion: "v1", + }, + }, + { + KMS: &config.KMSConfiguration{ + Name: "foo", + Endpoint: "unix:///tmp/kms-provider-2.socket", + Timeout: &metav1.Duration{Duration: 3 * time.Second}, + CacheSize: &cacheSize, + APIVersion: "v1", + }, + }, + }, + }, + }, + }, + want: field.ErrorList{}, + }, } for _, tt := range testCases { t.Run(tt.desc, func(t *testing.T) { got := ValidateEncryptionConfiguration(tt.in) if d := cmp.Diff(tt.want, got); d != "" { - t.Fatalf("EncryptionConfiguratoin validation results mismatch (-want +got):\n%s", d) + t.Fatalf("EncryptionConfiguration validation results mismatch (-want +got):\n%s", d) } }) } @@ -392,9 +571,10 @@ func TestKMSProviderName(t *testing.T) { nameField := field.NewPath("Resource").Index(0).Child("Provider").Index(0).Child("KMS").Child("name") testCases := []struct { - desc string - in *config.KMSConfiguration - want field.ErrorList + desc string + in *config.KMSConfiguration + kmsProviderNames sets.String + want field.ErrorList }{ { desc: "valid name", @@ -415,11 +595,24 @@ func TestKMSProviderName(t *testing.T) { field.Invalid(nameField, "foo:bar", fmt.Sprintf(invalidKMSConfigNameErrFmt, "foo:bar")), }, }, + { + desc: "invalid name with : but api version is v1", + in: &config.KMSConfiguration{Name: "foo:bar", APIVersion: "v1"}, + want: field.ErrorList{}, + }, + { + desc: "duplicate name", + in: &config.KMSConfiguration{Name: "foo"}, + kmsProviderNames: sets.NewString("foo"), + want: field.ErrorList{ + field.Invalid(nameField, "foo", fmt.Sprintf(duplicateKMSConfigNameErrFmt, "foo")), + }, + }, } for _, tt := range testCases { t.Run(tt.desc, func(t *testing.T) { - got := validateKMSConfigName(tt.in, nameField) + got := validateKMSConfigName(tt.in, nameField, tt.kmsProviderNames) if d := cmp.Diff(tt.want, got); d != "" { t.Fatalf("KMS Provider validation mismatch (-want +got):\n%s", d) } From 47f8c4bec63a2c4d6406cd615b41cd16f12be434 Mon Sep 17 00:00:00 2001 From: Anish Ramasekar Date: Mon, 7 Nov 2022 20:16:04 +0000 Subject: [PATCH 2/2] [KMS]: validate duplicate kms config name for v1 and v2 when reload=true Signed-off-by: Anish Ramasekar --- .../pkg/apis/config/validation/validation.go | 25 ++++--- .../apis/config/validation/validation_test.go | 75 +++++++++++++++++-- .../server/options/encryptionconfig/config.go | 6 +- .../options/encryptionconfig/config_test.go | 4 +- 4 files changed, 86 insertions(+), 24 deletions(-) diff --git a/staging/src/k8s.io/apiserver/pkg/apis/config/validation/validation.go b/staging/src/k8s.io/apiserver/pkg/apis/config/validation/validation.go index b453dcfa02b..84b2764df2b 100644 --- a/staging/src/k8s.io/apiserver/pkg/apis/config/validation/validation.go +++ b/staging/src/k8s.io/apiserver/pkg/apis/config/validation/validation.go @@ -55,7 +55,7 @@ var ( ) // ValidateEncryptionConfiguration validates a v1.EncryptionConfiguration. -func ValidateEncryptionConfiguration(c *config.EncryptionConfiguration) field.ErrorList { +func ValidateEncryptionConfiguration(c *config.EncryptionConfiguration, reload bool) field.ErrorList { allErrs := field.ErrorList{} if c == nil { @@ -88,7 +88,7 @@ func ValidateEncryptionConfiguration(c *config.EncryptionConfiguration) field.Er switch { case provider.KMS != nil: - allErrs = append(allErrs, validateKMSConfiguration(provider.KMS, path.Child("kms"), kmsProviderNames)...) + allErrs = append(allErrs, validateKMSConfiguration(provider.KMS, path.Child("kms"), kmsProviderNames, reload)...) kmsProviderNames.Insert(provider.KMS.Name) case provider.AESGCM != nil: allErrs = append(allErrs, validateKeys(provider.AESGCM.Keys, path.Child("aesgcm").Child("keys"), aesKeySizes)...) @@ -182,10 +182,10 @@ func validateKey(key config.Key, fieldPath *field.Path, expectedLen []int) field return allErrs } -func validateKMSConfiguration(c *config.KMSConfiguration, fieldPath *field.Path, kmsProviderNames sets.String) field.ErrorList { +func validateKMSConfiguration(c *config.KMSConfiguration, fieldPath *field.Path, kmsProviderNames sets.String, reload bool) field.ErrorList { allErrs := field.ErrorList{} - allErrs = append(allErrs, validateKMSConfigName(c, fieldPath.Child("name"), kmsProviderNames)...) + allErrs = append(allErrs, validateKMSConfigName(c, fieldPath.Child("name"), kmsProviderNames, reload)...) allErrs = append(allErrs, validateKMSTimeout(c, fieldPath.Child("timeout"))...) allErrs = append(allErrs, validateKMSEndpoint(c, fieldPath.Child("endpoint"))...) allErrs = append(allErrs, validateKMSCacheSize(c, fieldPath.Child("cachesize"))...) @@ -238,19 +238,20 @@ func validateKMSAPIVersion(c *config.KMSConfiguration, fieldPath *field.Path) fi return allErrs } -func validateKMSConfigName(c *config.KMSConfiguration, fieldPath *field.Path, kmsProviderNames sets.String) field.ErrorList { +func validateKMSConfigName(c *config.KMSConfiguration, fieldPath *field.Path, kmsProviderNames sets.String, reload bool) field.ErrorList { allErrs := field.ErrorList{} if c.Name == "" { allErrs = append(allErrs, field.Required(fieldPath, fmt.Sprintf(mandatoryFieldErrFmt, "name", "provider"))) } - if c.APIVersion != "v1" { - // kms v2 providers are not allowed to have a ":" in their name - if strings.Contains(c.Name, ":") { - allErrs = append(allErrs, field.Invalid(fieldPath, c.Name, fmt.Sprintf(invalidKMSConfigNameErrFmt, c.Name))) - } - // kms v2 providers name should be unique across all kms providers (v1 and v2) - // TODO(aramase): make this check for v1 and v2 (all kms versions) once https://github.com/kubernetes/kubernetes/pull/113529 is merged + // kms v2 providers are not allowed to have a ":" in their name + if c.APIVersion != "v1" && strings.Contains(c.Name, ":") { + allErrs = append(allErrs, field.Invalid(fieldPath, c.Name, fmt.Sprintf(invalidKMSConfigNameErrFmt, c.Name))) + } + + // kms v2 providers name must always be unique across all kms providers (v1 and v2) + // kms v1 provider names must be unique across all kms providers (v1 and v2) when hot reloading of encryption configuration is enabled (reload=true) + if reload || c.APIVersion != "v1" { if kmsProviderNames.Has(c.Name) { allErrs = append(allErrs, field.Invalid(fieldPath, c.Name, fmt.Sprintf(duplicateKMSConfigNameErrFmt, c.Name))) } diff --git a/staging/src/k8s.io/apiserver/pkg/apis/config/validation/validation_test.go b/staging/src/k8s.io/apiserver/pkg/apis/config/validation/validation_test.go index 01881004d4e..e3fa438ee26 100644 --- a/staging/src/k8s.io/apiserver/pkg/apis/config/validation/validation_test.go +++ b/staging/src/k8s.io/apiserver/pkg/apis/config/validation/validation_test.go @@ -32,9 +32,10 @@ func TestStructure(t *testing.T) { firstResourcePath := root.Index(0) cacheSize := int32(1) testCases := []struct { - desc string - in *config.EncryptionConfiguration - want field.ErrorList + desc string + in *config.EncryptionConfiguration + reload bool + want field.ErrorList }{ { desc: "nil encryption config", @@ -340,11 +341,46 @@ func TestStructure(t *testing.T) { }, want: field.ErrorList{}, }, + { + desc: "duplicate kms v1 config names should error when reload=true", + in: &config.EncryptionConfiguration{ + Resources: []config.ResourceConfiguration{ + { + Resources: []string{"secrets"}, + Providers: []config.ProviderConfiguration{ + { + KMS: &config.KMSConfiguration{ + Name: "foo", + Endpoint: "unix:///tmp/kms-provider-1.socket", + Timeout: &metav1.Duration{Duration: 3 * time.Second}, + CacheSize: &cacheSize, + APIVersion: "v1", + }, + }, + { + KMS: &config.KMSConfiguration{ + Name: "foo", + Endpoint: "unix:///tmp/kms-provider-2.socket", + Timeout: &metav1.Duration{Duration: 3 * time.Second}, + CacheSize: &cacheSize, + APIVersion: "v1", + }, + }, + }, + }, + }, + }, + reload: true, + want: field.ErrorList{ + field.Invalid(root.Index(0).Child("providers").Index(1).Child("kms").Child("name"), + "foo", fmt.Sprintf(duplicateKMSConfigNameErrFmt, "foo")), + }, + }, } for _, tt := range testCases { t.Run(tt.desc, func(t *testing.T) { - got := ValidateEncryptionConfiguration(tt.in) + got := ValidateEncryptionConfiguration(tt.in, tt.reload) if d := cmp.Diff(tt.want, got); d != "" { t.Fatalf("EncryptionConfiguration validation results mismatch (-want +got):\n%s", d) } @@ -573,6 +609,7 @@ func TestKMSProviderName(t *testing.T) { testCases := []struct { desc string in *config.KMSConfiguration + reload bool kmsProviderNames sets.String want field.ErrorList }{ @@ -601,8 +638,32 @@ func TestKMSProviderName(t *testing.T) { want: field.ErrorList{}, }, { - desc: "duplicate name", - in: &config.KMSConfiguration{Name: "foo"}, + desc: "duplicate name, kms v2, reload=false", + in: &config.KMSConfiguration{APIVersion: "v2", Name: "foo"}, + kmsProviderNames: sets.NewString("foo"), + want: field.ErrorList{ + field.Invalid(nameField, "foo", fmt.Sprintf(duplicateKMSConfigNameErrFmt, "foo")), + }, + }, + { + desc: "duplicate name, kms v2, reload=true", + in: &config.KMSConfiguration{APIVersion: "v2", Name: "foo"}, + reload: true, + kmsProviderNames: sets.NewString("foo"), + want: field.ErrorList{ + field.Invalid(nameField, "foo", fmt.Sprintf(duplicateKMSConfigNameErrFmt, "foo")), + }, + }, + { + desc: "duplicate name, kms v1, reload=false", + in: &config.KMSConfiguration{APIVersion: "v1", Name: "foo"}, + kmsProviderNames: sets.NewString("foo"), + want: field.ErrorList{}, + }, + { + desc: "duplicate name, kms v1, reload=true", + in: &config.KMSConfiguration{APIVersion: "v1", Name: "foo"}, + reload: true, kmsProviderNames: sets.NewString("foo"), want: field.ErrorList{ field.Invalid(nameField, "foo", fmt.Sprintf(duplicateKMSConfigNameErrFmt, "foo")), @@ -612,7 +673,7 @@ func TestKMSProviderName(t *testing.T) { for _, tt := range testCases { t.Run(tt.desc, func(t *testing.T) { - got := validateKMSConfigName(tt.in, nameField, tt.kmsProviderNames) + got := validateKMSConfigName(tt.in, nameField, tt.kmsProviderNames, tt.reload) if d := cmp.Diff(tt.want, got); d != "" { t.Fatalf("KMS Provider validation mismatch (-want +got):\n%s", d) } diff --git a/staging/src/k8s.io/apiserver/pkg/server/options/encryptionconfig/config.go b/staging/src/k8s.io/apiserver/pkg/server/options/encryptionconfig/config.go index c91d2f94d00..7b105dece4d 100644 --- a/staging/src/k8s.io/apiserver/pkg/server/options/encryptionconfig/config.go +++ b/staging/src/k8s.io/apiserver/pkg/server/options/encryptionconfig/config.go @@ -117,7 +117,7 @@ func (h *kmsv2PluginProbe) toHealthzCheck(idx int) healthz.HealthChecker { // It may launch multiple go routines whose lifecycle is controlled by stopCh. // If reload is true, or KMS v2 plugins are used with no KMS v1 plugins, the returned slice of health checkers will always be of length 1. func LoadEncryptionConfig(filepath string, reload bool, stopCh <-chan struct{}) (map[schema.GroupResource]value.Transformer, []healthz.HealthChecker, error) { - config, err := loadConfig(filepath) + config, err := loadConfig(filepath, reload) if err != nil { return nil, nil, fmt.Errorf("error while parsing file: %w", err) } @@ -262,7 +262,7 @@ func isKMSv2ProviderHealthy(name string, response *envelopekmsv2.StatusResponse) return nil } -func loadConfig(filepath string) (*apiserverconfig.EncryptionConfiguration, error) { +func loadConfig(filepath string, reload bool) (*apiserverconfig.EncryptionConfiguration, error) { f, err := os.Open(filepath) if err != nil { return nil, fmt.Errorf("error opening encryption provider configuration file %q: %w", filepath, err) @@ -291,7 +291,7 @@ func loadConfig(filepath string) (*apiserverconfig.EncryptionConfiguration, erro return nil, fmt.Errorf("got unexpected config type: %v", gvk) } - return config, validation.ValidateEncryptionConfiguration(config).ToAggregate() + return config, validation.ValidateEncryptionConfiguration(config, reload).ToAggregate() } func prefixTransformersAndProbes(config apiserverconfig.ResourceConfiguration, stopCh <-chan struct{}) ([]value.PrefixTransformer, []healthChecker, *kmsState, error) { diff --git a/staging/src/k8s.io/apiserver/pkg/server/options/encryptionconfig/config_test.go b/staging/src/k8s.io/apiserver/pkg/server/options/encryptionconfig/config_test.go index 4d1dfdb83dc..b0f54b8d12b 100644 --- a/staging/src/k8s.io/apiserver/pkg/server/options/encryptionconfig/config_test.go +++ b/staging/src/k8s.io/apiserver/pkg/server/options/encryptionconfig/config_test.go @@ -114,7 +114,7 @@ func newMockErrorEnvelopeKMSv2Service(endpoint string, timeout time.Duration) (e func TestLegacyConfig(t *testing.T) { legacyV1Config := "testdata/valid-configs/legacy.yaml" - legacyConfigObject, err := loadConfig(legacyV1Config) + legacyConfigObject, err := loadConfig(legacyV1Config, false) cacheSize := int32(10) if err != nil { t.Fatalf("error while parsing configuration file: %s.\nThe file was:\n%s", err, legacyV1Config) @@ -323,7 +323,7 @@ func TestKMSPluginHealthz(t *testing.T) { for _, tt := range testCases { t.Run(tt.desc, func(t *testing.T) { - config, err := loadConfig(tt.config) + config, err := loadConfig(tt.config, false) if errStr := errString(err); errStr != tt.wantErr { t.Fatalf("unexpected error state got=%s want=%s", errStr, tt.wantErr) }