diff --git a/pkg/features/versioned_kube_features.go b/pkg/features/versioned_kube_features.go
index 47f39308413..d7a3f63c14c 100644
--- a/pkg/features/versioned_kube_features.go
+++ b/pkg/features/versioned_kube_features.go
@@ -308,6 +308,7 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate
genericfeatures.StructuredAuthorizationConfiguration: {
{Version: version.MustParse("1.29"), Default: false, PreRelease: featuregate.Alpha},
{Version: version.MustParse("1.30"), Default: true, PreRelease: featuregate.Beta},
+ {Version: version.MustParse("1.32"), Default: true, PreRelease: featuregate.GA, LockToDefault: true},
},
genericfeatures.UnauthenticatedHTTP2DOSMitigation: {
diff --git a/staging/src/k8s.io/apiserver/pkg/apis/apiserver/load/load_test.go b/staging/src/k8s.io/apiserver/pkg/apis/apiserver/load/load_test.go
index c988b9957a1..1c5eb1d0dde 100644
--- a/staging/src/k8s.io/apiserver/pkg/apis/apiserver/load/load_test.go
+++ b/staging/src/k8s.io/apiserver/pkg/apis/apiserver/load/load_test.go
@@ -265,6 +265,45 @@ apiVersion: apiserver.config.k8s.io/v1beta1
kind: AuthorizationConfiguration
authorizers:
- type: Webhook
+`),
+ expectConfig: &api.AuthorizationConfiguration{
+ Authorizers: []api.AuthorizerConfiguration{{Type: "Webhook"}},
+ },
+ },
+ {
+ name: "v1 - json",
+ data: []byte(`{
+"apiVersion":"apiserver.config.k8s.io/v1",
+"kind":"AuthorizationConfiguration",
+"authorizers":[{"type":"Webhook"}]}`),
+ expectConfig: &api.AuthorizationConfiguration{
+ Authorizers: []api.AuthorizerConfiguration{{Type: "Webhook"}},
+ },
+ },
+ {
+ name: "v1 - defaults",
+ data: []byte(`{
+"apiVersion":"apiserver.config.k8s.io/v1",
+"kind":"AuthorizationConfiguration",
+"authorizers":[{"type":"Webhook","name":"default","webhook":{}}]}`),
+ expectConfig: &api.AuthorizationConfiguration{
+ Authorizers: []api.AuthorizerConfiguration{{
+ Type: "Webhook",
+ Name: "default",
+ Webhook: &api.WebhookConfiguration{
+ AuthorizedTTL: metav1.Duration{Duration: 5 * time.Minute},
+ UnauthorizedTTL: metav1.Duration{Duration: 30 * time.Second},
+ },
+ }},
+ },
+ },
+ {
+ name: "v1 - yaml",
+ data: []byte(`
+apiVersion: apiserver.config.k8s.io/v1
+kind: AuthorizationConfiguration
+authorizers:
+- type: Webhook
`),
expectConfig: &api.AuthorizationConfiguration{
Authorizers: []api.AuthorizerConfiguration{{Type: "Webhook"}},
diff --git a/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1/defaults.go b/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1/defaults.go
index b71b53c658b..46fb841a5f9 100644
--- a/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1/defaults.go
+++ b/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1/defaults.go
@@ -48,3 +48,12 @@ func SetDefaults_KMSConfiguration(obj *KMSConfiguration) {
obj.CacheSize = &defaultCacheSize
}
}
+
+func SetDefaults_WebhookConfiguration(obj *WebhookConfiguration) {
+ if obj.AuthorizedTTL.Duration == 0 {
+ obj.AuthorizedTTL.Duration = 5 * time.Minute
+ }
+ if obj.UnauthorizedTTL.Duration == 0 {
+ obj.UnauthorizedTTL.Duration = 30 * time.Second
+ }
+}
diff --git a/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1/register.go b/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1/register.go
index 0de8db49711..7b1b51b629d 100644
--- a/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1/register.go
+++ b/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1/register.go
@@ -47,6 +47,7 @@ func init() {
func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&AdmissionConfiguration{},
+ &AuthorizationConfiguration{},
&EncryptionConfiguration{},
)
// also register into the v1 group as EncryptionConfig (due to a docs bug)
diff --git a/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1/types.go b/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1/types.go
index e139dceb9de..e72109364f7 100644
--- a/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1/types.go
+++ b/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1/types.go
@@ -48,3 +48,122 @@ type AdmissionPluginConfiguration struct {
// +optional
Configuration *runtime.Unknown `json:"configuration"`
}
+
+// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
+
+type AuthorizationConfiguration struct {
+ metav1.TypeMeta
+
+ // Authorizers is an ordered list of authorizers to
+ // authorize requests against.
+ // This is similar to the --authorization-modes kube-apiserver flag
+ // Must be at least one.
+ Authorizers []AuthorizerConfiguration `json:"authorizers"`
+}
+
+const (
+ TypeWebhook AuthorizerType = "Webhook"
+ FailurePolicyNoOpinion string = "NoOpinion"
+ FailurePolicyDeny string = "Deny"
+ AuthorizationWebhookConnectionInfoTypeKubeConfigFile string = "KubeConfigFile"
+ AuthorizationWebhookConnectionInfoTypeInCluster string = "InClusterConfig"
+)
+
+type AuthorizerType string
+
+type AuthorizerConfiguration struct {
+ // Type refers to the type of the authorizer
+ // "Webhook" is supported in the generic API server
+ // Other API servers may support additional authorizer
+ // types like Node, RBAC, ABAC, etc.
+ Type string `json:"type"`
+
+ // Name used to describe the webhook
+ // This is explicitly used in monitoring machinery for metrics
+ // Note: Names must be DNS1123 labels like `myauthorizername` or
+ // subdomains like `myauthorizer.example.domain`
+ // Required, with no default
+ Name string `json:"name"`
+
+ // Webhook defines the configuration for a Webhook authorizer
+ // Must be defined when Type=Webhook
+ // Must not be defined when Type!=Webhook
+ Webhook *WebhookConfiguration `json:"webhook,omitempty"`
+}
+
+type WebhookConfiguration struct {
+ // The duration to cache 'authorized' responses from the webhook
+ // authorizer.
+ // Same as setting `--authorization-webhook-cache-authorized-ttl` flag
+ // Default: 5m0s
+ AuthorizedTTL metav1.Duration `json:"authorizedTTL"`
+ // The duration to cache 'unauthorized' responses from the webhook
+ // authorizer.
+ // Same as setting `--authorization-webhook-cache-unauthorized-ttl` flag
+ // Default: 30s
+ UnauthorizedTTL metav1.Duration `json:"unauthorizedTTL"`
+ // Timeout for the webhook request
+ // Maximum allowed value is 30s.
+ // Required, no default value.
+ Timeout metav1.Duration `json:"timeout"`
+ // The API version of the authorization.k8s.io SubjectAccessReview to
+ // send to and expect from the webhook.
+ // Same as setting `--authorization-webhook-version` flag
+ // Valid values: v1beta1, v1
+ // Required, no default value
+ SubjectAccessReviewVersion string `json:"subjectAccessReviewVersion"`
+ // MatchConditionSubjectAccessReviewVersion specifies the SubjectAccessReview
+ // version the CEL expressions are evaluated against
+ // Valid values: v1
+ // Required, no default value
+ MatchConditionSubjectAccessReviewVersion string `json:"matchConditionSubjectAccessReviewVersion"`
+ // Controls the authorization decision when a webhook request fails to
+ // complete or returns a malformed response or errors evaluating
+ // matchConditions.
+ // Valid values:
+ // - NoOpinion: continue to subsequent authorizers to see if one of
+ // them allows the request
+ // - Deny: reject the request without consulting subsequent authorizers
+ // Required, with no default.
+ FailurePolicy string `json:"failurePolicy"`
+
+ // ConnectionInfo defines how we talk to the webhook
+ ConnectionInfo WebhookConnectionInfo `json:"connectionInfo"`
+
+ // matchConditions is a list of conditions that must be met for a request to be sent to this
+ // webhook. An empty list of matchConditions matches all requests.
+ // There are a maximum of 64 match conditions allowed.
+ //
+ // The exact matching logic is (in order):
+ // 1. If at least one matchCondition evaluates to FALSE, then the webhook is skipped.
+ // 2. If ALL matchConditions evaluate to TRUE, then the webhook is called.
+ // 3. If at least one matchCondition evaluates to an error (but none are FALSE):
+ // - If failurePolicy=Deny, then the webhook rejects the request
+ // - If failurePolicy=NoOpinion, then the error is ignored and the webhook is skipped
+ MatchConditions []WebhookMatchCondition `json:"matchConditions"`
+}
+
+type WebhookConnectionInfo struct {
+ // Controls how the webhook should communicate with the server.
+ // Valid values:
+ // - KubeConfigFile: use the file specified in kubeConfigFile to locate the
+ // server.
+ // - InClusterConfig: use the in-cluster configuration to call the
+ // SubjectAccessReview API hosted by kube-apiserver. This mode is not
+ // allowed for kube-apiserver.
+ Type string `json:"type"`
+
+ // Path to KubeConfigFile for connection info
+ // Required, if connectionInfo.Type is KubeConfig
+ KubeConfigFile *string `json:"kubeConfigFile"`
+}
+
+type WebhookMatchCondition struct {
+ // expression represents the expression which will be evaluated by CEL. Must evaluate to bool.
+ // CEL expressions have access to the contents of the SubjectAccessReview in v1 version.
+ // If version specified by subjectAccessReviewVersion in the request variable is v1beta1,
+ // the contents would be converted to the v1 version before evaluating the CEL expression.
+ //
+ // Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/
+ Expression string `json:"expression"`
+}
diff --git a/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1/zz_generated.conversion.go b/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1/zz_generated.conversion.go
index c0f218742a3..63083025a53 100644
--- a/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1/zz_generated.conversion.go
+++ b/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1/zz_generated.conversion.go
@@ -67,6 +67,26 @@ func RegisterConversions(s *runtime.Scheme) error {
}); err != nil {
return err
}
+ if err := s.AddGeneratedConversionFunc((*AuthorizationConfiguration)(nil), (*apiserver.AuthorizationConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
+ return Convert_v1_AuthorizationConfiguration_To_apiserver_AuthorizationConfiguration(a.(*AuthorizationConfiguration), b.(*apiserver.AuthorizationConfiguration), scope)
+ }); err != nil {
+ return err
+ }
+ if err := s.AddGeneratedConversionFunc((*apiserver.AuthorizationConfiguration)(nil), (*AuthorizationConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
+ return Convert_apiserver_AuthorizationConfiguration_To_v1_AuthorizationConfiguration(a.(*apiserver.AuthorizationConfiguration), b.(*AuthorizationConfiguration), scope)
+ }); err != nil {
+ return err
+ }
+ if err := s.AddGeneratedConversionFunc((*AuthorizerConfiguration)(nil), (*apiserver.AuthorizerConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
+ return Convert_v1_AuthorizerConfiguration_To_apiserver_AuthorizerConfiguration(a.(*AuthorizerConfiguration), b.(*apiserver.AuthorizerConfiguration), scope)
+ }); err != nil {
+ return err
+ }
+ if err := s.AddGeneratedConversionFunc((*apiserver.AuthorizerConfiguration)(nil), (*AuthorizerConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
+ return Convert_apiserver_AuthorizerConfiguration_To_v1_AuthorizerConfiguration(a.(*apiserver.AuthorizerConfiguration), b.(*AuthorizerConfiguration), scope)
+ }); err != nil {
+ return err
+ }
if err := s.AddGeneratedConversionFunc((*EncryptionConfiguration)(nil), (*apiserver.EncryptionConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1_EncryptionConfiguration_To_apiserver_EncryptionConfiguration(a.(*EncryptionConfiguration), b.(*apiserver.EncryptionConfiguration), scope)
}); err != nil {
@@ -137,6 +157,36 @@ func RegisterConversions(s *runtime.Scheme) error {
}); err != nil {
return err
}
+ if err := s.AddGeneratedConversionFunc((*WebhookConfiguration)(nil), (*apiserver.WebhookConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
+ return Convert_v1_WebhookConfiguration_To_apiserver_WebhookConfiguration(a.(*WebhookConfiguration), b.(*apiserver.WebhookConfiguration), scope)
+ }); err != nil {
+ return err
+ }
+ if err := s.AddGeneratedConversionFunc((*apiserver.WebhookConfiguration)(nil), (*WebhookConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
+ return Convert_apiserver_WebhookConfiguration_To_v1_WebhookConfiguration(a.(*apiserver.WebhookConfiguration), b.(*WebhookConfiguration), scope)
+ }); err != nil {
+ return err
+ }
+ if err := s.AddGeneratedConversionFunc((*WebhookConnectionInfo)(nil), (*apiserver.WebhookConnectionInfo)(nil), func(a, b interface{}, scope conversion.Scope) error {
+ return Convert_v1_WebhookConnectionInfo_To_apiserver_WebhookConnectionInfo(a.(*WebhookConnectionInfo), b.(*apiserver.WebhookConnectionInfo), scope)
+ }); err != nil {
+ return err
+ }
+ if err := s.AddGeneratedConversionFunc((*apiserver.WebhookConnectionInfo)(nil), (*WebhookConnectionInfo)(nil), func(a, b interface{}, scope conversion.Scope) error {
+ return Convert_apiserver_WebhookConnectionInfo_To_v1_WebhookConnectionInfo(a.(*apiserver.WebhookConnectionInfo), b.(*WebhookConnectionInfo), scope)
+ }); err != nil {
+ return err
+ }
+ if err := s.AddGeneratedConversionFunc((*WebhookMatchCondition)(nil), (*apiserver.WebhookMatchCondition)(nil), func(a, b interface{}, scope conversion.Scope) error {
+ return Convert_v1_WebhookMatchCondition_To_apiserver_WebhookMatchCondition(a.(*WebhookMatchCondition), b.(*apiserver.WebhookMatchCondition), scope)
+ }); err != nil {
+ return err
+ }
+ if err := s.AddGeneratedConversionFunc((*apiserver.WebhookMatchCondition)(nil), (*WebhookMatchCondition)(nil), func(a, b interface{}, scope conversion.Scope) error {
+ return Convert_apiserver_WebhookMatchCondition_To_v1_WebhookMatchCondition(a.(*apiserver.WebhookMatchCondition), b.(*WebhookMatchCondition), scope)
+ }); err != nil {
+ return err
+ }
return nil
}
@@ -204,6 +254,50 @@ func Convert_apiserver_AdmissionPluginConfiguration_To_v1_AdmissionPluginConfigu
return autoConvert_apiserver_AdmissionPluginConfiguration_To_v1_AdmissionPluginConfiguration(in, out, s)
}
+func autoConvert_v1_AuthorizationConfiguration_To_apiserver_AuthorizationConfiguration(in *AuthorizationConfiguration, out *apiserver.AuthorizationConfiguration, s conversion.Scope) error {
+ out.Authorizers = *(*[]apiserver.AuthorizerConfiguration)(unsafe.Pointer(&in.Authorizers))
+ return nil
+}
+
+// Convert_v1_AuthorizationConfiguration_To_apiserver_AuthorizationConfiguration is an autogenerated conversion function.
+func Convert_v1_AuthorizationConfiguration_To_apiserver_AuthorizationConfiguration(in *AuthorizationConfiguration, out *apiserver.AuthorizationConfiguration, s conversion.Scope) error {
+ return autoConvert_v1_AuthorizationConfiguration_To_apiserver_AuthorizationConfiguration(in, out, s)
+}
+
+func autoConvert_apiserver_AuthorizationConfiguration_To_v1_AuthorizationConfiguration(in *apiserver.AuthorizationConfiguration, out *AuthorizationConfiguration, s conversion.Scope) error {
+ out.Authorizers = *(*[]AuthorizerConfiguration)(unsafe.Pointer(&in.Authorizers))
+ return nil
+}
+
+// Convert_apiserver_AuthorizationConfiguration_To_v1_AuthorizationConfiguration is an autogenerated conversion function.
+func Convert_apiserver_AuthorizationConfiguration_To_v1_AuthorizationConfiguration(in *apiserver.AuthorizationConfiguration, out *AuthorizationConfiguration, s conversion.Scope) error {
+ return autoConvert_apiserver_AuthorizationConfiguration_To_v1_AuthorizationConfiguration(in, out, s)
+}
+
+func autoConvert_v1_AuthorizerConfiguration_To_apiserver_AuthorizerConfiguration(in *AuthorizerConfiguration, out *apiserver.AuthorizerConfiguration, s conversion.Scope) error {
+ out.Type = apiserver.AuthorizerType(in.Type)
+ out.Name = in.Name
+ out.Webhook = (*apiserver.WebhookConfiguration)(unsafe.Pointer(in.Webhook))
+ return nil
+}
+
+// Convert_v1_AuthorizerConfiguration_To_apiserver_AuthorizerConfiguration is an autogenerated conversion function.
+func Convert_v1_AuthorizerConfiguration_To_apiserver_AuthorizerConfiguration(in *AuthorizerConfiguration, out *apiserver.AuthorizerConfiguration, s conversion.Scope) error {
+ return autoConvert_v1_AuthorizerConfiguration_To_apiserver_AuthorizerConfiguration(in, out, s)
+}
+
+func autoConvert_apiserver_AuthorizerConfiguration_To_v1_AuthorizerConfiguration(in *apiserver.AuthorizerConfiguration, out *AuthorizerConfiguration, s conversion.Scope) error {
+ out.Type = string(in.Type)
+ out.Name = in.Name
+ out.Webhook = (*WebhookConfiguration)(unsafe.Pointer(in.Webhook))
+ return nil
+}
+
+// Convert_apiserver_AuthorizerConfiguration_To_v1_AuthorizerConfiguration is an autogenerated conversion function.
+func Convert_apiserver_AuthorizerConfiguration_To_v1_AuthorizerConfiguration(in *apiserver.AuthorizerConfiguration, out *AuthorizerConfiguration, s conversion.Scope) error {
+ return autoConvert_apiserver_AuthorizerConfiguration_To_v1_AuthorizerConfiguration(in, out, s)
+}
+
func autoConvert_v1_EncryptionConfiguration_To_apiserver_EncryptionConfiguration(in *EncryptionConfiguration, out *apiserver.EncryptionConfiguration, s conversion.Scope) error {
out.Resources = *(*[]apiserver.ResourceConfiguration)(unsafe.Pointer(&in.Resources))
return nil
@@ -361,3 +455,83 @@ func autoConvert_apiserver_SecretboxConfiguration_To_v1_SecretboxConfiguration(i
func Convert_apiserver_SecretboxConfiguration_To_v1_SecretboxConfiguration(in *apiserver.SecretboxConfiguration, out *SecretboxConfiguration, s conversion.Scope) error {
return autoConvert_apiserver_SecretboxConfiguration_To_v1_SecretboxConfiguration(in, out, s)
}
+
+func autoConvert_v1_WebhookConfiguration_To_apiserver_WebhookConfiguration(in *WebhookConfiguration, out *apiserver.WebhookConfiguration, s conversion.Scope) error {
+ out.AuthorizedTTL = in.AuthorizedTTL
+ out.UnauthorizedTTL = in.UnauthorizedTTL
+ out.Timeout = in.Timeout
+ out.SubjectAccessReviewVersion = in.SubjectAccessReviewVersion
+ out.MatchConditionSubjectAccessReviewVersion = in.MatchConditionSubjectAccessReviewVersion
+ out.FailurePolicy = in.FailurePolicy
+ if err := Convert_v1_WebhookConnectionInfo_To_apiserver_WebhookConnectionInfo(&in.ConnectionInfo, &out.ConnectionInfo, s); err != nil {
+ return err
+ }
+ out.MatchConditions = *(*[]apiserver.WebhookMatchCondition)(unsafe.Pointer(&in.MatchConditions))
+ return nil
+}
+
+// Convert_v1_WebhookConfiguration_To_apiserver_WebhookConfiguration is an autogenerated conversion function.
+func Convert_v1_WebhookConfiguration_To_apiserver_WebhookConfiguration(in *WebhookConfiguration, out *apiserver.WebhookConfiguration, s conversion.Scope) error {
+ return autoConvert_v1_WebhookConfiguration_To_apiserver_WebhookConfiguration(in, out, s)
+}
+
+func autoConvert_apiserver_WebhookConfiguration_To_v1_WebhookConfiguration(in *apiserver.WebhookConfiguration, out *WebhookConfiguration, s conversion.Scope) error {
+ out.AuthorizedTTL = in.AuthorizedTTL
+ out.UnauthorizedTTL = in.UnauthorizedTTL
+ out.Timeout = in.Timeout
+ out.SubjectAccessReviewVersion = in.SubjectAccessReviewVersion
+ out.MatchConditionSubjectAccessReviewVersion = in.MatchConditionSubjectAccessReviewVersion
+ out.FailurePolicy = in.FailurePolicy
+ if err := Convert_apiserver_WebhookConnectionInfo_To_v1_WebhookConnectionInfo(&in.ConnectionInfo, &out.ConnectionInfo, s); err != nil {
+ return err
+ }
+ out.MatchConditions = *(*[]WebhookMatchCondition)(unsafe.Pointer(&in.MatchConditions))
+ return nil
+}
+
+// Convert_apiserver_WebhookConfiguration_To_v1_WebhookConfiguration is an autogenerated conversion function.
+func Convert_apiserver_WebhookConfiguration_To_v1_WebhookConfiguration(in *apiserver.WebhookConfiguration, out *WebhookConfiguration, s conversion.Scope) error {
+ return autoConvert_apiserver_WebhookConfiguration_To_v1_WebhookConfiguration(in, out, s)
+}
+
+func autoConvert_v1_WebhookConnectionInfo_To_apiserver_WebhookConnectionInfo(in *WebhookConnectionInfo, out *apiserver.WebhookConnectionInfo, s conversion.Scope) error {
+ out.Type = in.Type
+ out.KubeConfigFile = (*string)(unsafe.Pointer(in.KubeConfigFile))
+ return nil
+}
+
+// Convert_v1_WebhookConnectionInfo_To_apiserver_WebhookConnectionInfo is an autogenerated conversion function.
+func Convert_v1_WebhookConnectionInfo_To_apiserver_WebhookConnectionInfo(in *WebhookConnectionInfo, out *apiserver.WebhookConnectionInfo, s conversion.Scope) error {
+ return autoConvert_v1_WebhookConnectionInfo_To_apiserver_WebhookConnectionInfo(in, out, s)
+}
+
+func autoConvert_apiserver_WebhookConnectionInfo_To_v1_WebhookConnectionInfo(in *apiserver.WebhookConnectionInfo, out *WebhookConnectionInfo, s conversion.Scope) error {
+ out.Type = in.Type
+ out.KubeConfigFile = (*string)(unsafe.Pointer(in.KubeConfigFile))
+ return nil
+}
+
+// Convert_apiserver_WebhookConnectionInfo_To_v1_WebhookConnectionInfo is an autogenerated conversion function.
+func Convert_apiserver_WebhookConnectionInfo_To_v1_WebhookConnectionInfo(in *apiserver.WebhookConnectionInfo, out *WebhookConnectionInfo, s conversion.Scope) error {
+ return autoConvert_apiserver_WebhookConnectionInfo_To_v1_WebhookConnectionInfo(in, out, s)
+}
+
+func autoConvert_v1_WebhookMatchCondition_To_apiserver_WebhookMatchCondition(in *WebhookMatchCondition, out *apiserver.WebhookMatchCondition, s conversion.Scope) error {
+ out.Expression = in.Expression
+ return nil
+}
+
+// Convert_v1_WebhookMatchCondition_To_apiserver_WebhookMatchCondition is an autogenerated conversion function.
+func Convert_v1_WebhookMatchCondition_To_apiserver_WebhookMatchCondition(in *WebhookMatchCondition, out *apiserver.WebhookMatchCondition, s conversion.Scope) error {
+ return autoConvert_v1_WebhookMatchCondition_To_apiserver_WebhookMatchCondition(in, out, s)
+}
+
+func autoConvert_apiserver_WebhookMatchCondition_To_v1_WebhookMatchCondition(in *apiserver.WebhookMatchCondition, out *WebhookMatchCondition, s conversion.Scope) error {
+ out.Expression = in.Expression
+ return nil
+}
+
+// Convert_apiserver_WebhookMatchCondition_To_v1_WebhookMatchCondition is an autogenerated conversion function.
+func Convert_apiserver_WebhookMatchCondition_To_v1_WebhookMatchCondition(in *apiserver.WebhookMatchCondition, out *WebhookMatchCondition, s conversion.Scope) error {
+ return autoConvert_apiserver_WebhookMatchCondition_To_v1_WebhookMatchCondition(in, out, s)
+}
diff --git a/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1/zz_generated.deepcopy.go b/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1/zz_generated.deepcopy.go
index cbdcaa5a06c..6afdbd3a2cc 100644
--- a/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1/zz_generated.deepcopy.go
+++ b/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1/zz_generated.deepcopy.go
@@ -100,6 +100,59 @@ func (in *AdmissionPluginConfiguration) DeepCopy() *AdmissionPluginConfiguration
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *AuthorizationConfiguration) DeepCopyInto(out *AuthorizationConfiguration) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ if in.Authorizers != nil {
+ in, out := &in.Authorizers, &out.Authorizers
+ *out = make([]AuthorizerConfiguration, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthorizationConfiguration.
+func (in *AuthorizationConfiguration) DeepCopy() *AuthorizationConfiguration {
+ if in == nil {
+ return nil
+ }
+ out := new(AuthorizationConfiguration)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *AuthorizationConfiguration) DeepCopyObject() runtime.Object {
+ if c := in.DeepCopy(); c != nil {
+ return c
+ }
+ return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *AuthorizerConfiguration) DeepCopyInto(out *AuthorizerConfiguration) {
+ *out = *in
+ if in.Webhook != nil {
+ in, out := &in.Webhook, &out.Webhook
+ *out = new(WebhookConfiguration)
+ (*in).DeepCopyInto(*out)
+ }
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthorizerConfiguration.
+func (in *AuthorizerConfiguration) DeepCopy() *AuthorizerConfiguration {
+ if in == nil {
+ return nil
+ }
+ out := new(AuthorizerConfiguration)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *EncryptionConfiguration) DeepCopyInto(out *EncryptionConfiguration) {
*out = *in
@@ -279,3 +332,65 @@ func (in *SecretboxConfiguration) DeepCopy() *SecretboxConfiguration {
in.DeepCopyInto(out)
return out
}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *WebhookConfiguration) DeepCopyInto(out *WebhookConfiguration) {
+ *out = *in
+ out.AuthorizedTTL = in.AuthorizedTTL
+ out.UnauthorizedTTL = in.UnauthorizedTTL
+ out.Timeout = in.Timeout
+ in.ConnectionInfo.DeepCopyInto(&out.ConnectionInfo)
+ if in.MatchConditions != nil {
+ in, out := &in.MatchConditions, &out.MatchConditions
+ *out = make([]WebhookMatchCondition, len(*in))
+ copy(*out, *in)
+ }
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WebhookConfiguration.
+func (in *WebhookConfiguration) DeepCopy() *WebhookConfiguration {
+ if in == nil {
+ return nil
+ }
+ out := new(WebhookConfiguration)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *WebhookConnectionInfo) DeepCopyInto(out *WebhookConnectionInfo) {
+ *out = *in
+ if in.KubeConfigFile != nil {
+ in, out := &in.KubeConfigFile, &out.KubeConfigFile
+ *out = new(string)
+ **out = **in
+ }
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WebhookConnectionInfo.
+func (in *WebhookConnectionInfo) DeepCopy() *WebhookConnectionInfo {
+ if in == nil {
+ return nil
+ }
+ out := new(WebhookConnectionInfo)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *WebhookMatchCondition) DeepCopyInto(out *WebhookMatchCondition) {
+ *out = *in
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WebhookMatchCondition.
+func (in *WebhookMatchCondition) DeepCopy() *WebhookMatchCondition {
+ if in == nil {
+ return nil
+ }
+ out := new(WebhookMatchCondition)
+ in.DeepCopyInto(out)
+ return out
+}
diff --git a/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1/zz_generated.defaults.go b/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1/zz_generated.defaults.go
index 82fec011102..4c8189b1317 100644
--- a/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1/zz_generated.defaults.go
+++ b/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1/zz_generated.defaults.go
@@ -29,10 +29,20 @@ import (
// Public to allow building arbitrary schemes.
// All generated defaulters are covering - they call all nested defaulters.
func RegisterDefaults(scheme *runtime.Scheme) error {
+ scheme.AddTypeDefaultingFunc(&AuthorizationConfiguration{}, func(obj interface{}) { SetObjectDefaults_AuthorizationConfiguration(obj.(*AuthorizationConfiguration)) })
scheme.AddTypeDefaultingFunc(&EncryptionConfiguration{}, func(obj interface{}) { SetObjectDefaults_EncryptionConfiguration(obj.(*EncryptionConfiguration)) })
return nil
}
+func SetObjectDefaults_AuthorizationConfiguration(in *AuthorizationConfiguration) {
+ for i := range in.Authorizers {
+ a := &in.Authorizers[i]
+ if a.Webhook != nil {
+ SetDefaults_WebhookConfiguration(a.Webhook)
+ }
+ }
+}
+
func SetObjectDefaults_EncryptionConfiguration(in *EncryptionConfiguration) {
for i := range in.Resources {
a := &in.Resources[i]
diff --git a/staging/src/k8s.io/apiserver/pkg/apis/apiserver/validation/validation_test.go b/staging/src/k8s.io/apiserver/pkg/apis/apiserver/validation/validation_test.go
index b2cbfd90548..2e39d375f1c 100644
--- a/staging/src/k8s.io/apiserver/pkg/apis/apiserver/validation/validation_test.go
+++ b/staging/src/k8s.io/apiserver/pkg/apis/apiserver/validation/validation_test.go
@@ -1686,8 +1686,6 @@ type (
)
func TestValidateAuthorizationConfiguration(t *testing.T) {
- featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StructuredAuthorizationConfiguration, true)
-
badKubeConfigFile := "../some/relative/path/kubeconfig"
tempKubeConfigFile, err := os.CreateTemp("/tmp", "kubeconfig")
@@ -2481,7 +2479,6 @@ func TestValidateAndCompileMatchConditions(t *testing.T) {
testCases := []struct {
name string
matchConditions []api.WebhookMatchCondition
- featureEnabled bool
expectedErr string
}{
{
@@ -2494,26 +2491,11 @@ func TestValidateAndCompileMatchConditions(t *testing.T) {
Expression: "request.user == 'admin'",
},
},
- featureEnabled: true,
- expectedErr: "",
- },
- {
- name: "should fail when match conditions are used without feature enabled",
- matchConditions: []api.WebhookMatchCondition{
- {
- Expression: "has(request.resourceAttributes) && request.resourceAttributes.namespace == 'kube-system'",
- },
- {
- Expression: "request.user == 'admin'",
- },
- },
- featureEnabled: false,
- expectedErr: `matchConditions: Invalid value: "": matchConditions are not supported when StructuredAuthorizationConfiguration feature gate is disabled`,
+ expectedErr: "",
},
{
name: "no matchConditions should not require feature enablement",
matchConditions: []api.WebhookMatchCondition{},
- featureEnabled: false,
expectedErr: "",
},
{
@@ -2523,8 +2505,7 @@ func TestValidateAndCompileMatchConditions(t *testing.T) {
Expression: " ",
},
},
- featureEnabled: true,
- expectedErr: "matchConditions[0].expression: Required value",
+ expectedErr: "matchConditions[0].expression: Required value",
},
{
name: "match conditions with duplicate expressions",
@@ -2536,8 +2517,7 @@ func TestValidateAndCompileMatchConditions(t *testing.T) {
Expression: "request.user == 'admin'",
},
},
- featureEnabled: true,
- expectedErr: `matchConditions[1].expression: Duplicate value: "request.user == 'admin'"`,
+ expectedErr: `matchConditions[1].expression: Duplicate value: "request.user == 'admin'"`,
},
{
name: "match conditions with undeclared reference",
@@ -2546,8 +2526,7 @@ func TestValidateAndCompileMatchConditions(t *testing.T) {
Expression: "test",
},
},
- featureEnabled: true,
- expectedErr: "matchConditions[0].expression: Invalid value: \"test\": compilation failed: ERROR: :1:1: undeclared reference to 'test' (in container '')\n | test\n | ^",
+ expectedErr: "matchConditions[0].expression: Invalid value: \"test\": compilation failed: ERROR: :1:1: undeclared reference to 'test' (in container '')\n | test\n | ^",
},
{
name: "match conditions with bad return type",
@@ -2556,14 +2535,12 @@ func TestValidateAndCompileMatchConditions(t *testing.T) {
Expression: "request.user = 'test'",
},
},
- featureEnabled: true,
- expectedErr: "matchConditions[0].expression: Invalid value: \"request.user = 'test'\": compilation failed: ERROR: :1:14: Syntax error: token recognition error at: '= '\n | request.user = 'test'\n | .............^\nERROR: :1:16: Syntax error: extraneous input ''test'' expecting \n | request.user = 'test'\n | ...............^",
+ expectedErr: "matchConditions[0].expression: Invalid value: \"request.user = 'test'\": compilation failed: ERROR: :1:14: Syntax error: token recognition error at: '= '\n | request.user = 'test'\n | .............^\nERROR: :1:16: Syntax error: extraneous input ''test'' expecting \n | request.user = 'test'\n | ...............^",
},
}
for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
- featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StructuredAuthorizationConfiguration, tt.featureEnabled)
celMatcher, errList := ValidateAndCompileMatchConditions(authorizationcel.NewDefaultCompiler(), tt.matchConditions)
if len(tt.expectedErr) == 0 && len(tt.matchConditions) > 0 && len(errList) == 0 && celMatcher == nil {
t.Errorf("celMatcher should not be nil when there are matchCondition and no error returned")
diff --git a/staging/src/k8s.io/apiserver/pkg/features/kube_features.go b/staging/src/k8s.io/apiserver/pkg/features/kube_features.go
index c17f2849a62..f70644cd4d4 100644
--- a/staging/src/k8s.io/apiserver/pkg/features/kube_features.go
+++ b/staging/src/k8s.io/apiserver/pkg/features/kube_features.go
@@ -373,6 +373,7 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate
StructuredAuthorizationConfiguration: {
{Version: version.MustParse("1.29"), Default: false, PreRelease: featuregate.Alpha},
{Version: version.MustParse("1.30"), Default: true, PreRelease: featuregate.Beta},
+ {Version: version.MustParse("1.32"), Default: true, PreRelease: featuregate.GA, LockToDefault: true},
},
UnauthenticatedHTTP2DOSMitigation: {
diff --git a/staging/src/k8s.io/apiserver/plugin/pkg/authorizer/webhook/webhook_v1_test.go b/staging/src/k8s.io/apiserver/plugin/pkg/authorizer/webhook/webhook_v1_test.go
index ea058c9d5e7..7d22897c235 100644
--- a/staging/src/k8s.io/apiserver/plugin/pkg/authorizer/webhook/webhook_v1_test.go
+++ b/staging/src/k8s.io/apiserver/plugin/pkg/authorizer/webhook/webhook_v1_test.go
@@ -590,7 +590,6 @@ func TestV1WebhookCache(t *testing.T) {
t.Fatal(err)
}
defer s.Close()
- featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StructuredAuthorizationConfiguration, true)
expressions := []apiserver.WebhookMatchCondition{
{
Expression: "has(request.resourceAttributes) && request.resourceAttributes.namespace == 'kittensandponies'",
@@ -711,7 +710,6 @@ func TestStructuredAuthzConfigFeatureEnablement(t *testing.T) {
expectedEvalErr bool
expectedDecision authorizer.Decision
expressions []apiserver.WebhookMatchCondition
- featureEnabled bool
selectorEnabled bool
}
aliceAttr := authorizer.AttributesRecord{
@@ -746,20 +744,6 @@ func TestStructuredAuthzConfigFeatureEnablement(t *testing.T) {
expectedCompileErr: false,
expectedDecision: authorizer.DecisionAllow,
expressions: []apiserver.WebhookMatchCondition{},
- featureEnabled: false,
- },
- {
- name: "should fail when match conditions are used without feature enabled",
- attr: aliceAttr,
- allow: false,
- expectedCompileErr: true,
- expectedDecision: authorizer.DecisionNoOpinion,
- expressions: []apiserver.WebhookMatchCondition{
- {
- Expression: "request.user == 'alice'",
- },
- },
- featureEnabled: false,
},
{
name: "feature enabled, match all against all expressions",
@@ -793,14 +777,12 @@ func TestStructuredAuthzConfigFeatureEnablement(t *testing.T) {
Expression: "request.resourceAttributes.labelSelector.?requirements.orValue([]).exists(r, r.key=='baz' && r.operator=='In' && ('qux' in r.values))",
},
},
- featureEnabled: true,
selectorEnabled: true,
},
}
for i, test := range tests {
t.Run(test.name, func(t *testing.T) {
- featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StructuredAuthorizationConfiguration, test.featureEnabled)
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.AuthorizeWithSelectors, test.selectorEnabled)
// create new compiler because it depends on the feature gate
@@ -837,7 +819,6 @@ func TestWebhookMetrics(t *testing.T) {
t.Fatal(err)
}
defer s.Close()
- featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StructuredAuthorizationConfiguration, true)
aliceAttr := authorizer.AttributesRecord{
User: &user.DefaultInfo{
@@ -934,23 +915,13 @@ func TestWebhookMetrics(t *testing.T) {
}
}
-func BenchmarkNoCELExpressionFeatureOff(b *testing.B) {
- expressions := []apiserver.WebhookMatchCondition{}
- b.Run("compile", func(b *testing.B) {
- benchmarkNewWebhookAuthorizer(b, expressions, false)
- })
- b.Run("authorize", func(b *testing.B) {
- benchmarkWebhookAuthorize(b, expressions, false)
- })
-}
-
func BenchmarkNoCELExpressionFeatureOn(b *testing.B) {
expressions := []apiserver.WebhookMatchCondition{}
b.Run("compile", func(b *testing.B) {
- benchmarkNewWebhookAuthorizer(b, expressions, true)
+ benchmarkNewWebhookAuthorizer(b, expressions)
})
b.Run("authorize", func(b *testing.B) {
- benchmarkWebhookAuthorize(b, expressions, true)
+ benchmarkWebhookAuthorize(b, expressions)
})
}
func BenchmarkWithOneCELExpressions(b *testing.B) {
@@ -960,10 +931,10 @@ func BenchmarkWithOneCELExpressions(b *testing.B) {
},
}
b.Run("compile", func(b *testing.B) {
- benchmarkNewWebhookAuthorizer(b, expressions, true)
+ benchmarkNewWebhookAuthorizer(b, expressions)
})
b.Run("authorize", func(b *testing.B) {
- benchmarkWebhookAuthorize(b, expressions, true)
+ benchmarkWebhookAuthorize(b, expressions)
})
}
func BenchmarkWithOneCELExpressionsFalse(b *testing.B) {
@@ -973,10 +944,10 @@ func BenchmarkWithOneCELExpressionsFalse(b *testing.B) {
},
}
b.Run("compile", func(b *testing.B) {
- benchmarkNewWebhookAuthorizer(b, expressions, true)
+ benchmarkNewWebhookAuthorizer(b, expressions)
})
b.Run("authorize", func(b *testing.B) {
- benchmarkWebhookAuthorize(b, expressions, true)
+ benchmarkWebhookAuthorize(b, expressions)
})
}
func BenchmarkWithTwoCELExpressions(b *testing.B) {
@@ -989,10 +960,10 @@ func BenchmarkWithTwoCELExpressions(b *testing.B) {
},
}
b.Run("compile", func(b *testing.B) {
- benchmarkNewWebhookAuthorizer(b, expressions, true)
+ benchmarkNewWebhookAuthorizer(b, expressions)
})
b.Run("authorize", func(b *testing.B) {
- benchmarkWebhookAuthorize(b, expressions, true)
+ benchmarkWebhookAuthorize(b, expressions)
})
}
func BenchmarkWithTwoCELExpressionsFalse(b *testing.B) {
@@ -1005,10 +976,10 @@ func BenchmarkWithTwoCELExpressionsFalse(b *testing.B) {
},
}
b.Run("compile", func(b *testing.B) {
- benchmarkNewWebhookAuthorizer(b, expressions, true)
+ benchmarkNewWebhookAuthorizer(b, expressions)
})
b.Run("authorize", func(b *testing.B) {
- benchmarkWebhookAuthorize(b, expressions, true)
+ benchmarkWebhookAuthorize(b, expressions)
})
}
func BenchmarkWithManyCELExpressions(b *testing.B) {
@@ -1039,10 +1010,10 @@ func BenchmarkWithManyCELExpressions(b *testing.B) {
},
}
b.Run("compile", func(b *testing.B) {
- benchmarkNewWebhookAuthorizer(b, expressions, true)
+ benchmarkNewWebhookAuthorizer(b, expressions)
})
b.Run("authorize", func(b *testing.B) {
- benchmarkWebhookAuthorize(b, expressions, true)
+ benchmarkWebhookAuthorize(b, expressions)
})
}
func BenchmarkWithManyCELExpressionsFalse(b *testing.B) {
@@ -1073,14 +1044,14 @@ func BenchmarkWithManyCELExpressionsFalse(b *testing.B) {
},
}
b.Run("compile", func(b *testing.B) {
- benchmarkNewWebhookAuthorizer(b, expressions, true)
+ benchmarkNewWebhookAuthorizer(b, expressions)
})
b.Run("authorize", func(b *testing.B) {
- benchmarkWebhookAuthorize(b, expressions, true)
+ benchmarkWebhookAuthorize(b, expressions)
})
}
-func benchmarkNewWebhookAuthorizer(b *testing.B, expressions []apiserver.WebhookMatchCondition, featureEnabled bool) {
+func benchmarkNewWebhookAuthorizer(b *testing.B, expressions []apiserver.WebhookMatchCondition) {
service := new(mockV1Service)
service.statusCode = 200
service.Allow()
@@ -1089,7 +1060,6 @@ func benchmarkNewWebhookAuthorizer(b *testing.B, expressions []apiserver.Webhook
b.Fatal(err)
}
defer s.Close()
- featuregatetesting.SetFeatureGateDuringTest(b, utilfeature.DefaultFeatureGate, features.StructuredAuthorizationConfiguration, featureEnabled)
b.ResetTimer()
for i := 0; i < b.N; i++ {
@@ -1102,7 +1072,7 @@ func benchmarkNewWebhookAuthorizer(b *testing.B, expressions []apiserver.Webhook
b.StopTimer()
}
-func benchmarkWebhookAuthorize(b *testing.B, expressions []apiserver.WebhookMatchCondition, featureEnabled bool) {
+func benchmarkWebhookAuthorize(b *testing.B, expressions []apiserver.WebhookMatchCondition) {
attr := authorizer.AttributesRecord{
User: &user.DefaultInfo{
Name: "alice",
@@ -1122,7 +1092,6 @@ func benchmarkWebhookAuthorize(b *testing.B, expressions []apiserver.WebhookMatc
b.Fatal(err)
}
defer s.Close()
- featuregatetesting.SetFeatureGateDuringTest(b, utilfeature.DefaultFeatureGate, features.StructuredAuthorizationConfiguration, featureEnabled)
// Create an authorizer with or without expressions to compile
wh, err := newV1Authorizer(s.URL, clientCert, clientKey, caCert, 0, noopAuthorizerMetrics(), authorizationcel.NewDefaultCompiler(), expressions, "")
if err != nil {
@@ -1142,7 +1111,6 @@ func benchmarkWebhookAuthorize(b *testing.B, expressions []apiserver.WebhookMatc
// TestV1WebhookMatchConditions verifies cel expressions are compiled and evaluated correctly
func TestV1WebhookMatchConditions(t *testing.T) {
- featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StructuredAuthorizationConfiguration, true)
service := new(mockV1Service)
service.statusCode = 200
service.Allow()
diff --git a/test/featuregates_linter/test_data/versioned_feature_list.yaml b/test/featuregates_linter/test_data/versioned_feature_list.yaml
index cd039bf5608..188d98a550a 100644
--- a/test/featuregates_linter/test_data/versioned_feature_list.yaml
+++ b/test/featuregates_linter/test_data/versioned_feature_list.yaml
@@ -1182,6 +1182,10 @@
lockToDefault: false
preRelease: Beta
version: "1.30"
+ - default: true
+ lockToDefault: true
+ preRelease: GA
+ version: "1.32"
- name: SupplementalGroupsPolicy
versionedSpecs:
- default: false
diff --git a/test/integration/auth/authz_config_test.go b/test/integration/auth/authz_config_test.go
index d062786baf2..ef4ff057721 100644
--- a/test/integration/auth/authz_config_test.go
+++ b/test/integration/auth/authz_config_test.go
@@ -54,8 +54,6 @@ import (
)
func TestAuthzConfig(t *testing.T) {
- featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StructuredAuthorizationConfiguration, true)
-
dir := t.TempDir()
configFileName := filepath.Join(dir, "config.yaml")
if err := atomicWriteFile(configFileName, []byte(`
@@ -126,7 +124,6 @@ authorizers:
func TestMultiWebhookAuthzConfig(t *testing.T) {
authzmetrics.ResetMetricsForTest()
defer authzmetrics.ResetMetricsForTest()
- featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StructuredAuthorizationConfiguration, true)
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.AuthorizeWithSelectors, true)
dir := t.TempDir()
@@ -415,7 +412,7 @@ users:
configFileName := filepath.Join(dir, "config.yaml")
if err := atomicWriteFile(configFileName, []byte(`
-apiVersion: apiserver.config.k8s.io/v1alpha1
+apiVersion: apiserver.config.k8s.io/v1beta1
kind: AuthorizationConfiguration
authorizers:
- type: Webhook
@@ -803,7 +800,7 @@ authorizers:
// write good config with different webhook
if err := atomicWriteFile(configFileName, []byte(`
-apiVersion: apiserver.config.k8s.io/v1beta1
+apiVersion: apiserver.config.k8s.io/v1
kind: AuthorizationConfiguration
authorizers:
- type: Webhook