mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-27 13:37:30 +00:00
KEP-3221: Promote StructuredAuthorizationConfiguration to GA
This commit is contained in:
parent
ded7ad554e
commit
ad808e609a
@ -308,6 +308,7 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate
|
|||||||
genericfeatures.StructuredAuthorizationConfiguration: {
|
genericfeatures.StructuredAuthorizationConfiguration: {
|
||||||
{Version: version.MustParse("1.29"), Default: false, PreRelease: featuregate.Alpha},
|
{Version: version.MustParse("1.29"), Default: false, PreRelease: featuregate.Alpha},
|
||||||
{Version: version.MustParse("1.30"), Default: true, PreRelease: featuregate.Beta},
|
{Version: version.MustParse("1.30"), Default: true, PreRelease: featuregate.Beta},
|
||||||
|
{Version: version.MustParse("1.32"), Default: true, PreRelease: featuregate.GA, LockToDefault: true},
|
||||||
},
|
},
|
||||||
|
|
||||||
genericfeatures.UnauthenticatedHTTP2DOSMitigation: {
|
genericfeatures.UnauthenticatedHTTP2DOSMitigation: {
|
||||||
|
@ -265,6 +265,45 @@ apiVersion: apiserver.config.k8s.io/v1beta1
|
|||||||
kind: AuthorizationConfiguration
|
kind: AuthorizationConfiguration
|
||||||
authorizers:
|
authorizers:
|
||||||
- type: Webhook
|
- 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{
|
expectConfig: &api.AuthorizationConfiguration{
|
||||||
Authorizers: []api.AuthorizerConfiguration{{Type: "Webhook"}},
|
Authorizers: []api.AuthorizerConfiguration{{Type: "Webhook"}},
|
||||||
|
@ -48,3 +48,12 @@ func SetDefaults_KMSConfiguration(obj *KMSConfiguration) {
|
|||||||
obj.CacheSize = &defaultCacheSize
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -47,6 +47,7 @@ func init() {
|
|||||||
func addKnownTypes(scheme *runtime.Scheme) error {
|
func addKnownTypes(scheme *runtime.Scheme) error {
|
||||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||||
&AdmissionConfiguration{},
|
&AdmissionConfiguration{},
|
||||||
|
&AuthorizationConfiguration{},
|
||||||
&EncryptionConfiguration{},
|
&EncryptionConfiguration{},
|
||||||
)
|
)
|
||||||
// also register into the v1 group as EncryptionConfig (due to a docs bug)
|
// also register into the v1 group as EncryptionConfig (due to a docs bug)
|
||||||
|
@ -48,3 +48,122 @@ type AdmissionPluginConfiguration struct {
|
|||||||
// +optional
|
// +optional
|
||||||
Configuration *runtime.Unknown `json:"configuration"`
|
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"`
|
||||||
|
}
|
||||||
|
@ -67,6 +67,26 @@ func RegisterConversions(s *runtime.Scheme) error {
|
|||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
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 {
|
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)
|
return Convert_v1_EncryptionConfiguration_To_apiserver_EncryptionConfiguration(a.(*EncryptionConfiguration), b.(*apiserver.EncryptionConfiguration), scope)
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
@ -137,6 +157,36 @@ func RegisterConversions(s *runtime.Scheme) error {
|
|||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,6 +254,50 @@ func Convert_apiserver_AdmissionPluginConfiguration_To_v1_AdmissionPluginConfigu
|
|||||||
return autoConvert_apiserver_AdmissionPluginConfiguration_To_v1_AdmissionPluginConfiguration(in, out, s)
|
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 {
|
func autoConvert_v1_EncryptionConfiguration_To_apiserver_EncryptionConfiguration(in *EncryptionConfiguration, out *apiserver.EncryptionConfiguration, s conversion.Scope) error {
|
||||||
out.Resources = *(*[]apiserver.ResourceConfiguration)(unsafe.Pointer(&in.Resources))
|
out.Resources = *(*[]apiserver.ResourceConfiguration)(unsafe.Pointer(&in.Resources))
|
||||||
return nil
|
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 {
|
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)
|
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)
|
||||||
|
}
|
||||||
|
@ -100,6 +100,59 @@ func (in *AdmissionPluginConfiguration) DeepCopy() *AdmissionPluginConfiguration
|
|||||||
return out
|
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.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *EncryptionConfiguration) DeepCopyInto(out *EncryptionConfiguration) {
|
func (in *EncryptionConfiguration) DeepCopyInto(out *EncryptionConfiguration) {
|
||||||
*out = *in
|
*out = *in
|
||||||
@ -279,3 +332,65 @@ func (in *SecretboxConfiguration) DeepCopy() *SecretboxConfiguration {
|
|||||||
in.DeepCopyInto(out)
|
in.DeepCopyInto(out)
|
||||||
return 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
|
||||||
|
}
|
||||||
|
@ -29,10 +29,20 @@ import (
|
|||||||
// Public to allow building arbitrary schemes.
|
// Public to allow building arbitrary schemes.
|
||||||
// All generated defaulters are covering - they call all nested defaulters.
|
// All generated defaulters are covering - they call all nested defaulters.
|
||||||
func RegisterDefaults(scheme *runtime.Scheme) error {
|
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)) })
|
scheme.AddTypeDefaultingFunc(&EncryptionConfiguration{}, func(obj interface{}) { SetObjectDefaults_EncryptionConfiguration(obj.(*EncryptionConfiguration)) })
|
||||||
return nil
|
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) {
|
func SetObjectDefaults_EncryptionConfiguration(in *EncryptionConfiguration) {
|
||||||
for i := range in.Resources {
|
for i := range in.Resources {
|
||||||
a := &in.Resources[i]
|
a := &in.Resources[i]
|
||||||
|
@ -1686,8 +1686,6 @@ type (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestValidateAuthorizationConfiguration(t *testing.T) {
|
func TestValidateAuthorizationConfiguration(t *testing.T) {
|
||||||
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StructuredAuthorizationConfiguration, true)
|
|
||||||
|
|
||||||
badKubeConfigFile := "../some/relative/path/kubeconfig"
|
badKubeConfigFile := "../some/relative/path/kubeconfig"
|
||||||
|
|
||||||
tempKubeConfigFile, err := os.CreateTemp("/tmp", "kubeconfig")
|
tempKubeConfigFile, err := os.CreateTemp("/tmp", "kubeconfig")
|
||||||
@ -2481,7 +2479,6 @@ func TestValidateAndCompileMatchConditions(t *testing.T) {
|
|||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
matchConditions []api.WebhookMatchCondition
|
matchConditions []api.WebhookMatchCondition
|
||||||
featureEnabled bool
|
|
||||||
expectedErr string
|
expectedErr string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
@ -2494,26 +2491,11 @@ func TestValidateAndCompileMatchConditions(t *testing.T) {
|
|||||||
Expression: "request.user == 'admin'",
|
Expression: "request.user == 'admin'",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
featureEnabled: true,
|
|
||||||
expectedErr: "",
|
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`,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "no matchConditions should not require feature enablement",
|
name: "no matchConditions should not require feature enablement",
|
||||||
matchConditions: []api.WebhookMatchCondition{},
|
matchConditions: []api.WebhookMatchCondition{},
|
||||||
featureEnabled: false,
|
|
||||||
expectedErr: "",
|
expectedErr: "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -2523,7 +2505,6 @@ func TestValidateAndCompileMatchConditions(t *testing.T) {
|
|||||||
Expression: " ",
|
Expression: " ",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
featureEnabled: true,
|
|
||||||
expectedErr: "matchConditions[0].expression: Required value",
|
expectedErr: "matchConditions[0].expression: Required value",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -2536,7 +2517,6 @@ func TestValidateAndCompileMatchConditions(t *testing.T) {
|
|||||||
Expression: "request.user == 'admin'",
|
Expression: "request.user == 'admin'",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
featureEnabled: true,
|
|
||||||
expectedErr: `matchConditions[1].expression: Duplicate value: "request.user == 'admin'"`,
|
expectedErr: `matchConditions[1].expression: Duplicate value: "request.user == 'admin'"`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -2546,7 +2526,6 @@ func TestValidateAndCompileMatchConditions(t *testing.T) {
|
|||||||
Expression: "test",
|
Expression: "test",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
featureEnabled: true,
|
|
||||||
expectedErr: "matchConditions[0].expression: Invalid value: \"test\": compilation failed: ERROR: <input>:1:1: undeclared reference to 'test' (in container '')\n | test\n | ^",
|
expectedErr: "matchConditions[0].expression: Invalid value: \"test\": compilation failed: ERROR: <input>:1:1: undeclared reference to 'test' (in container '')\n | test\n | ^",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -2556,14 +2535,12 @@ func TestValidateAndCompileMatchConditions(t *testing.T) {
|
|||||||
Expression: "request.user = 'test'",
|
Expression: "request.user = 'test'",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
featureEnabled: true,
|
|
||||||
expectedErr: "matchConditions[0].expression: Invalid value: \"request.user = 'test'\": compilation failed: ERROR: <input>:1:14: Syntax error: token recognition error at: '= '\n | request.user = 'test'\n | .............^\nERROR: <input>:1:16: Syntax error: extraneous input ''test'' expecting <EOF>\n | request.user = 'test'\n | ...............^",
|
expectedErr: "matchConditions[0].expression: Invalid value: \"request.user = 'test'\": compilation failed: ERROR: <input>:1:14: Syntax error: token recognition error at: '= '\n | request.user = 'test'\n | .............^\nERROR: <input>:1:16: Syntax error: extraneous input ''test'' expecting <EOF>\n | request.user = 'test'\n | ...............^",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range testCases {
|
for _, tt := range testCases {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StructuredAuthorizationConfiguration, tt.featureEnabled)
|
|
||||||
celMatcher, errList := ValidateAndCompileMatchConditions(authorizationcel.NewDefaultCompiler(), tt.matchConditions)
|
celMatcher, errList := ValidateAndCompileMatchConditions(authorizationcel.NewDefaultCompiler(), tt.matchConditions)
|
||||||
if len(tt.expectedErr) == 0 && len(tt.matchConditions) > 0 && len(errList) == 0 && celMatcher == nil {
|
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")
|
t.Errorf("celMatcher should not be nil when there are matchCondition and no error returned")
|
||||||
|
@ -373,6 +373,7 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate
|
|||||||
StructuredAuthorizationConfiguration: {
|
StructuredAuthorizationConfiguration: {
|
||||||
{Version: version.MustParse("1.29"), Default: false, PreRelease: featuregate.Alpha},
|
{Version: version.MustParse("1.29"), Default: false, PreRelease: featuregate.Alpha},
|
||||||
{Version: version.MustParse("1.30"), Default: true, PreRelease: featuregate.Beta},
|
{Version: version.MustParse("1.30"), Default: true, PreRelease: featuregate.Beta},
|
||||||
|
{Version: version.MustParse("1.32"), Default: true, PreRelease: featuregate.GA, LockToDefault: true},
|
||||||
},
|
},
|
||||||
|
|
||||||
UnauthenticatedHTTP2DOSMitigation: {
|
UnauthenticatedHTTP2DOSMitigation: {
|
||||||
|
@ -590,7 +590,6 @@ func TestV1WebhookCache(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StructuredAuthorizationConfiguration, true)
|
|
||||||
expressions := []apiserver.WebhookMatchCondition{
|
expressions := []apiserver.WebhookMatchCondition{
|
||||||
{
|
{
|
||||||
Expression: "has(request.resourceAttributes) && request.resourceAttributes.namespace == 'kittensandponies'",
|
Expression: "has(request.resourceAttributes) && request.resourceAttributes.namespace == 'kittensandponies'",
|
||||||
@ -711,7 +710,6 @@ func TestStructuredAuthzConfigFeatureEnablement(t *testing.T) {
|
|||||||
expectedEvalErr bool
|
expectedEvalErr bool
|
||||||
expectedDecision authorizer.Decision
|
expectedDecision authorizer.Decision
|
||||||
expressions []apiserver.WebhookMatchCondition
|
expressions []apiserver.WebhookMatchCondition
|
||||||
featureEnabled bool
|
|
||||||
selectorEnabled bool
|
selectorEnabled bool
|
||||||
}
|
}
|
||||||
aliceAttr := authorizer.AttributesRecord{
|
aliceAttr := authorizer.AttributesRecord{
|
||||||
@ -746,20 +744,6 @@ func TestStructuredAuthzConfigFeatureEnablement(t *testing.T) {
|
|||||||
expectedCompileErr: false,
|
expectedCompileErr: false,
|
||||||
expectedDecision: authorizer.DecisionAllow,
|
expectedDecision: authorizer.DecisionAllow,
|
||||||
expressions: []apiserver.WebhookMatchCondition{},
|
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",
|
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))",
|
Expression: "request.resourceAttributes.labelSelector.?requirements.orValue([]).exists(r, r.key=='baz' && r.operator=='In' && ('qux' in r.values))",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
featureEnabled: true,
|
|
||||||
selectorEnabled: true,
|
selectorEnabled: true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, test := range tests {
|
for i, test := range tests {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
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)
|
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.AuthorizeWithSelectors, test.selectorEnabled)
|
||||||
|
|
||||||
// create new compiler because it depends on the feature gate
|
// create new compiler because it depends on the feature gate
|
||||||
@ -837,7 +819,6 @@ func TestWebhookMetrics(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StructuredAuthorizationConfiguration, true)
|
|
||||||
|
|
||||||
aliceAttr := authorizer.AttributesRecord{
|
aliceAttr := authorizer.AttributesRecord{
|
||||||
User: &user.DefaultInfo{
|
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) {
|
func BenchmarkNoCELExpressionFeatureOn(b *testing.B) {
|
||||||
expressions := []apiserver.WebhookMatchCondition{}
|
expressions := []apiserver.WebhookMatchCondition{}
|
||||||
b.Run("compile", func(b *testing.B) {
|
b.Run("compile", func(b *testing.B) {
|
||||||
benchmarkNewWebhookAuthorizer(b, expressions, true)
|
benchmarkNewWebhookAuthorizer(b, expressions)
|
||||||
})
|
})
|
||||||
b.Run("authorize", func(b *testing.B) {
|
b.Run("authorize", func(b *testing.B) {
|
||||||
benchmarkWebhookAuthorize(b, expressions, true)
|
benchmarkWebhookAuthorize(b, expressions)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
func BenchmarkWithOneCELExpressions(b *testing.B) {
|
func BenchmarkWithOneCELExpressions(b *testing.B) {
|
||||||
@ -960,10 +931,10 @@ func BenchmarkWithOneCELExpressions(b *testing.B) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
b.Run("compile", func(b *testing.B) {
|
b.Run("compile", func(b *testing.B) {
|
||||||
benchmarkNewWebhookAuthorizer(b, expressions, true)
|
benchmarkNewWebhookAuthorizer(b, expressions)
|
||||||
})
|
})
|
||||||
b.Run("authorize", func(b *testing.B) {
|
b.Run("authorize", func(b *testing.B) {
|
||||||
benchmarkWebhookAuthorize(b, expressions, true)
|
benchmarkWebhookAuthorize(b, expressions)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
func BenchmarkWithOneCELExpressionsFalse(b *testing.B) {
|
func BenchmarkWithOneCELExpressionsFalse(b *testing.B) {
|
||||||
@ -973,10 +944,10 @@ func BenchmarkWithOneCELExpressionsFalse(b *testing.B) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
b.Run("compile", func(b *testing.B) {
|
b.Run("compile", func(b *testing.B) {
|
||||||
benchmarkNewWebhookAuthorizer(b, expressions, true)
|
benchmarkNewWebhookAuthorizer(b, expressions)
|
||||||
})
|
})
|
||||||
b.Run("authorize", func(b *testing.B) {
|
b.Run("authorize", func(b *testing.B) {
|
||||||
benchmarkWebhookAuthorize(b, expressions, true)
|
benchmarkWebhookAuthorize(b, expressions)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
func BenchmarkWithTwoCELExpressions(b *testing.B) {
|
func BenchmarkWithTwoCELExpressions(b *testing.B) {
|
||||||
@ -989,10 +960,10 @@ func BenchmarkWithTwoCELExpressions(b *testing.B) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
b.Run("compile", func(b *testing.B) {
|
b.Run("compile", func(b *testing.B) {
|
||||||
benchmarkNewWebhookAuthorizer(b, expressions, true)
|
benchmarkNewWebhookAuthorizer(b, expressions)
|
||||||
})
|
})
|
||||||
b.Run("authorize", func(b *testing.B) {
|
b.Run("authorize", func(b *testing.B) {
|
||||||
benchmarkWebhookAuthorize(b, expressions, true)
|
benchmarkWebhookAuthorize(b, expressions)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
func BenchmarkWithTwoCELExpressionsFalse(b *testing.B) {
|
func BenchmarkWithTwoCELExpressionsFalse(b *testing.B) {
|
||||||
@ -1005,10 +976,10 @@ func BenchmarkWithTwoCELExpressionsFalse(b *testing.B) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
b.Run("compile", func(b *testing.B) {
|
b.Run("compile", func(b *testing.B) {
|
||||||
benchmarkNewWebhookAuthorizer(b, expressions, true)
|
benchmarkNewWebhookAuthorizer(b, expressions)
|
||||||
})
|
})
|
||||||
b.Run("authorize", func(b *testing.B) {
|
b.Run("authorize", func(b *testing.B) {
|
||||||
benchmarkWebhookAuthorize(b, expressions, true)
|
benchmarkWebhookAuthorize(b, expressions)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
func BenchmarkWithManyCELExpressions(b *testing.B) {
|
func BenchmarkWithManyCELExpressions(b *testing.B) {
|
||||||
@ -1039,10 +1010,10 @@ func BenchmarkWithManyCELExpressions(b *testing.B) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
b.Run("compile", func(b *testing.B) {
|
b.Run("compile", func(b *testing.B) {
|
||||||
benchmarkNewWebhookAuthorizer(b, expressions, true)
|
benchmarkNewWebhookAuthorizer(b, expressions)
|
||||||
})
|
})
|
||||||
b.Run("authorize", func(b *testing.B) {
|
b.Run("authorize", func(b *testing.B) {
|
||||||
benchmarkWebhookAuthorize(b, expressions, true)
|
benchmarkWebhookAuthorize(b, expressions)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
func BenchmarkWithManyCELExpressionsFalse(b *testing.B) {
|
func BenchmarkWithManyCELExpressionsFalse(b *testing.B) {
|
||||||
@ -1073,14 +1044,14 @@ func BenchmarkWithManyCELExpressionsFalse(b *testing.B) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
b.Run("compile", func(b *testing.B) {
|
b.Run("compile", func(b *testing.B) {
|
||||||
benchmarkNewWebhookAuthorizer(b, expressions, true)
|
benchmarkNewWebhookAuthorizer(b, expressions)
|
||||||
})
|
})
|
||||||
b.Run("authorize", func(b *testing.B) {
|
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 := new(mockV1Service)
|
||||||
service.statusCode = 200
|
service.statusCode = 200
|
||||||
service.Allow()
|
service.Allow()
|
||||||
@ -1089,7 +1060,6 @@ func benchmarkNewWebhookAuthorizer(b *testing.B, expressions []apiserver.Webhook
|
|||||||
b.Fatal(err)
|
b.Fatal(err)
|
||||||
}
|
}
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
featuregatetesting.SetFeatureGateDuringTest(b, utilfeature.DefaultFeatureGate, features.StructuredAuthorizationConfiguration, featureEnabled)
|
|
||||||
|
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
@ -1102,7 +1072,7 @@ func benchmarkNewWebhookAuthorizer(b *testing.B, expressions []apiserver.Webhook
|
|||||||
b.StopTimer()
|
b.StopTimer()
|
||||||
}
|
}
|
||||||
|
|
||||||
func benchmarkWebhookAuthorize(b *testing.B, expressions []apiserver.WebhookMatchCondition, featureEnabled bool) {
|
func benchmarkWebhookAuthorize(b *testing.B, expressions []apiserver.WebhookMatchCondition) {
|
||||||
attr := authorizer.AttributesRecord{
|
attr := authorizer.AttributesRecord{
|
||||||
User: &user.DefaultInfo{
|
User: &user.DefaultInfo{
|
||||||
Name: "alice",
|
Name: "alice",
|
||||||
@ -1122,7 +1092,6 @@ func benchmarkWebhookAuthorize(b *testing.B, expressions []apiserver.WebhookMatc
|
|||||||
b.Fatal(err)
|
b.Fatal(err)
|
||||||
}
|
}
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
featuregatetesting.SetFeatureGateDuringTest(b, utilfeature.DefaultFeatureGate, features.StructuredAuthorizationConfiguration, featureEnabled)
|
|
||||||
// Create an authorizer with or without expressions to compile
|
// Create an authorizer with or without expressions to compile
|
||||||
wh, err := newV1Authorizer(s.URL, clientCert, clientKey, caCert, 0, noopAuthorizerMetrics(), authorizationcel.NewDefaultCompiler(), expressions, "")
|
wh, err := newV1Authorizer(s.URL, clientCert, clientKey, caCert, 0, noopAuthorizerMetrics(), authorizationcel.NewDefaultCompiler(), expressions, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1142,7 +1111,6 @@ func benchmarkWebhookAuthorize(b *testing.B, expressions []apiserver.WebhookMatc
|
|||||||
|
|
||||||
// TestV1WebhookMatchConditions verifies cel expressions are compiled and evaluated correctly
|
// TestV1WebhookMatchConditions verifies cel expressions are compiled and evaluated correctly
|
||||||
func TestV1WebhookMatchConditions(t *testing.T) {
|
func TestV1WebhookMatchConditions(t *testing.T) {
|
||||||
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StructuredAuthorizationConfiguration, true)
|
|
||||||
service := new(mockV1Service)
|
service := new(mockV1Service)
|
||||||
service.statusCode = 200
|
service.statusCode = 200
|
||||||
service.Allow()
|
service.Allow()
|
||||||
|
@ -1182,6 +1182,10 @@
|
|||||||
lockToDefault: false
|
lockToDefault: false
|
||||||
preRelease: Beta
|
preRelease: Beta
|
||||||
version: "1.30"
|
version: "1.30"
|
||||||
|
- default: true
|
||||||
|
lockToDefault: true
|
||||||
|
preRelease: GA
|
||||||
|
version: "1.32"
|
||||||
- name: SupplementalGroupsPolicy
|
- name: SupplementalGroupsPolicy
|
||||||
versionedSpecs:
|
versionedSpecs:
|
||||||
- default: false
|
- default: false
|
||||||
|
@ -54,8 +54,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestAuthzConfig(t *testing.T) {
|
func TestAuthzConfig(t *testing.T) {
|
||||||
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StructuredAuthorizationConfiguration, true)
|
|
||||||
|
|
||||||
dir := t.TempDir()
|
dir := t.TempDir()
|
||||||
configFileName := filepath.Join(dir, "config.yaml")
|
configFileName := filepath.Join(dir, "config.yaml")
|
||||||
if err := atomicWriteFile(configFileName, []byte(`
|
if err := atomicWriteFile(configFileName, []byte(`
|
||||||
@ -126,7 +124,6 @@ authorizers:
|
|||||||
func TestMultiWebhookAuthzConfig(t *testing.T) {
|
func TestMultiWebhookAuthzConfig(t *testing.T) {
|
||||||
authzmetrics.ResetMetricsForTest()
|
authzmetrics.ResetMetricsForTest()
|
||||||
defer authzmetrics.ResetMetricsForTest()
|
defer authzmetrics.ResetMetricsForTest()
|
||||||
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StructuredAuthorizationConfiguration, true)
|
|
||||||
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.AuthorizeWithSelectors, true)
|
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.AuthorizeWithSelectors, true)
|
||||||
|
|
||||||
dir := t.TempDir()
|
dir := t.TempDir()
|
||||||
@ -415,7 +412,7 @@ users:
|
|||||||
|
|
||||||
configFileName := filepath.Join(dir, "config.yaml")
|
configFileName := filepath.Join(dir, "config.yaml")
|
||||||
if err := atomicWriteFile(configFileName, []byte(`
|
if err := atomicWriteFile(configFileName, []byte(`
|
||||||
apiVersion: apiserver.config.k8s.io/v1alpha1
|
apiVersion: apiserver.config.k8s.io/v1beta1
|
||||||
kind: AuthorizationConfiguration
|
kind: AuthorizationConfiguration
|
||||||
authorizers:
|
authorizers:
|
||||||
- type: Webhook
|
- type: Webhook
|
||||||
@ -803,7 +800,7 @@ authorizers:
|
|||||||
|
|
||||||
// write good config with different webhook
|
// write good config with different webhook
|
||||||
if err := atomicWriteFile(configFileName, []byte(`
|
if err := atomicWriteFile(configFileName, []byte(`
|
||||||
apiVersion: apiserver.config.k8s.io/v1beta1
|
apiVersion: apiserver.config.k8s.io/v1
|
||||||
kind: AuthorizationConfiguration
|
kind: AuthorizationConfiguration
|
||||||
authorizers:
|
authorizers:
|
||||||
- type: Webhook
|
- type: Webhook
|
||||||
|
Loading…
Reference in New Issue
Block a user