refuse to allow apiserver to startup if ServiceAccountTokenNodeBinding is enabled without ServiceAccountTokenNodeBindingValidation

This commit is contained in:
James Munnelly 2024-02-06 14:03:50 +00:00
parent dfc20d19c8
commit e087acc791
2 changed files with 26 additions and 7 deletions

View File

@ -260,6 +260,11 @@ func (o *BuiltInAuthenticationOptions) Validate() []error {
}
}
// verify that if ServiceAccountTokenNodeBinding is enabled, ServiceAccountTokenNodeBindingValidation is also enabled.
if utilfeature.DefaultFeatureGate.Enabled(features.ServiceAccountTokenNodeBinding) && !utilfeature.DefaultFeatureGate.Enabled(features.ServiceAccountTokenNodeBindingValidation) {
allErrors = append(allErrors, fmt.Errorf("the %q feature gate can only be enabled if the %q feature gate is also enabled", features.ServiceAccountTokenNodeBinding, features.ServiceAccountTokenNodeBindingValidation))
}
if o.WebHook != nil {
retryBackoff := o.WebHook.RetryBackoff
if retryBackoff != nil && retryBackoff.Steps <= 0 {

View File

@ -35,19 +35,22 @@ import (
"k8s.io/apiserver/pkg/features"
apiserveroptions "k8s.io/apiserver/pkg/server/options"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/component-base/featuregate"
featuregatetesting "k8s.io/component-base/featuregate/testing"
kubefeatures "k8s.io/kubernetes/pkg/features"
kubeauthenticator "k8s.io/kubernetes/pkg/kubeapiserver/authenticator"
"k8s.io/utils/pointer"
)
func TestAuthenticationValidate(t *testing.T) {
testCases := []struct {
name string
testOIDC *OIDCAuthenticationOptions
testSA *ServiceAccountAuthenticationOptions
testWebHook *WebHookAuthenticationOptions
testAuthenticationConfigFile string
expectErr string
name string
testOIDC *OIDCAuthenticationOptions
testSA *ServiceAccountAuthenticationOptions
testWebHook *WebHookAuthenticationOptions
testAuthenticationConfigFile string
expectErr string
enabledFeatures, disabledFeatures []featuregate.Feature
}{
{
name: "test when OIDC and ServiceAccounts are nil",
@ -226,6 +229,12 @@ func TestAuthenticationValidate(t *testing.T) {
},
expectErr: "authentication-config file and oidc-* flags are mutually exclusive",
},
{
name: "fails to validate if ServiceAccountTokenNodeBindingValidation is disabled and ServiceAccountTokenNodeBinding is enabled",
enabledFeatures: []featuregate.Feature{kubefeatures.ServiceAccountTokenNodeBinding},
disabledFeatures: []featuregate.Feature{kubefeatures.ServiceAccountTokenNodeBindingValidation},
expectErr: "the \"ServiceAccountTokenNodeBinding\" feature gate can only be enabled if the \"ServiceAccountTokenNodeBindingValidation\" feature gate is also enabled",
},
}
for _, testcase := range testCases {
@ -235,7 +244,12 @@ func TestAuthenticationValidate(t *testing.T) {
options.ServiceAccounts = testcase.testSA
options.WebHook = testcase.testWebHook
options.AuthenticationConfigFile = testcase.testAuthenticationConfigFile
for _, f := range testcase.enabledFeatures {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, f, true)()
}
for _, f := range testcase.disabledFeatures {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, f, false)()
}
errs := options.Validate()
if len(errs) > 0 && (!strings.Contains(utilerrors.NewAggregate(errs).Error(), testcase.expectErr) || testcase.expectErr == "") {
t.Errorf("Got err: %v, Expected err: %s", errs, testcase.expectErr)