diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json index 52cac37b953..8d476ce04c7 100644 --- a/api/openapi-spec/swagger.json +++ b/api/openapi-spec/swagger.json @@ -11064,7 +11064,7 @@ "description": "`distinguisherMethod` defines how to compute the flow distinguisher for requests that match this schema. `nil` specifies that the distinguisher is disabled and thus will always be the empty string." }, "matchingPrecedence": { - "description": "`matchingPrecedence` is used to choose among the FlowSchemas that match a given request. The chosen FlowSchema is among those with the numerically lowest (which we take to be logically highest) MatchingPrecedence. Each MatchingPrecedence value must be non-negative. Note that if the precedence is not specified or zero, it will be set to 1000 as default.", + "description": "`matchingPrecedence` is used to choose among the FlowSchemas that match a given request. The chosen FlowSchema is among those with the numerically lowest (which we take to be logically highest) MatchingPrecedence. Each MatchingPrecedence value must be ranged in [1,10000]. Note that if the precedence is not specified, it will be set to 1000 as default.", "format": "int32", "type": "integer" }, diff --git a/pkg/apis/flowcontrol/types.go b/pkg/apis/flowcontrol/types.go index ffc54af6c3f..21d3233378e 100644 --- a/pkg/apis/flowcontrol/types.go +++ b/pkg/apis/flowcontrol/types.go @@ -43,6 +43,11 @@ const ( PriorityLevelConfigurationConditionConcurrencyShared = "ConcurrencyShared" ) +// Constants used by api validation. +const ( + FlowSchemaMaxMatchingPrecedence int32 = 10000 +) + // +genclient // +genclient:nonNamespaced // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object @@ -88,8 +93,8 @@ type FlowSchemaSpec struct { PriorityLevelConfiguration PriorityLevelConfigurationReference // `matchingPrecedence` is used to choose among the FlowSchemas that match a given request. The chosen // FlowSchema is among those with the numerically lowest (which we take to be logically highest) - // MatchingPrecedence. Each MatchingPrecedence value must be non-negative. - // Note that if the precedence is not specified or zero, it will be set to 1000 as default. + // MatchingPrecedence. Each MatchingPrecedence value must be ranged in [1,10000]. + // Note that if the precedence is not specified, it will be set to 1000 as default. // +optional MatchingPrecedence int32 // `distinguisherMethod` defines how to compute the flow distinguisher for requests that match this schema. diff --git a/pkg/apis/flowcontrol/validation/validation.go b/pkg/apis/flowcontrol/validation/validation.go index 1fd6da9ca35..669db97808c 100644 --- a/pkg/apis/flowcontrol/validation/validation.go +++ b/pkg/apis/flowcontrol/validation/validation.go @@ -87,7 +87,10 @@ func ValidateFlowSchemaUpdate(old, fs *flowcontrol.FlowSchema) field.ErrorList { func ValidateFlowSchemaSpec(spec *flowcontrol.FlowSchemaSpec, fldPath *field.Path) field.ErrorList { var allErrs field.ErrorList if spec.MatchingPrecedence <= 0 { - allErrs = append(allErrs, field.Invalid(fldPath.Child("matchingPrecedence"), spec.MatchingPrecedence, "must be positive value")) + allErrs = append(allErrs, field.Invalid(fldPath.Child("matchingPrecedence"), spec.MatchingPrecedence, "must be a positive value")) + } + if spec.MatchingPrecedence > flowcontrol.FlowSchemaMaxMatchingPrecedence { + allErrs = append(allErrs, field.Invalid(fldPath.Child("matchingPrecedence"), spec.MatchingPrecedence, fmt.Sprintf("must not be greater than %v", flowcontrol.FlowSchemaMaxMatchingPrecedence))) } if spec.DistinguisherMethod != nil { if !supportedDistinguisherMethods.Has(string(spec.DistinguisherMethod.Type)) { diff --git a/pkg/apis/flowcontrol/validation/validation_test.go b/pkg/apis/flowcontrol/validation/validation_test.go index dc1c93b6e7f..3d398fe9d53 100644 --- a/pkg/apis/flowcontrol/validation/validation_test.go +++ b/pkg/apis/flowcontrol/validation/validation_test.go @@ -547,6 +547,41 @@ func TestFlowSchemaValidation(t *testing.T) { field.Invalid(field.NewPath("spec").Child("rules").Index(0).Child("resourceRules").Index(0).Child("namespaces").Index(0), "-foo", nsErrIntro+`a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?')`), }, }, + { + name: "MatchingPrecedence must not be greater than 10000", + flowSchema: &flowcontrol.FlowSchema{ + ObjectMeta: metav1.ObjectMeta{ + Name: "system-foo", + }, + Spec: flowcontrol.FlowSchemaSpec{ + MatchingPrecedence: 50000, + PriorityLevelConfiguration: flowcontrol.PriorityLevelConfigurationReference{ + Name: "system-bar", + }, + Rules: []flowcontrol.PolicyRulesWithSubjects{ + { + Subjects: []flowcontrol.Subject{ + { + Kind: flowcontrol.SubjectKindUser, + User: &flowcontrol.UserSubject{Name: "noxu"}, + }, + }, + ResourceRules: []flowcontrol.ResourcePolicyRule{ + { + Verbs: []string{flowcontrol.VerbAll}, + APIGroups: []string{flowcontrol.APIGroupAll}, + Resources: []string{flowcontrol.ResourceAll}, + Namespaces: []string{flowcontrol.NamespaceEvery}, + }, + }, + }, + }, + }, + }, + expectedErrors: field.ErrorList{ + field.Invalid(field.NewPath("spec").Child("matchingPrecedence"), int32(50000), "must not be greater than 10000"), + }, + }, } for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { diff --git a/staging/src/k8s.io/api/flowcontrol/v1alpha1/generated.proto b/staging/src/k8s.io/api/flowcontrol/v1alpha1/generated.proto index 6134b5e6999..65143d29fc9 100644 --- a/staging/src/k8s.io/api/flowcontrol/v1alpha1/generated.proto +++ b/staging/src/k8s.io/api/flowcontrol/v1alpha1/generated.proto @@ -97,8 +97,8 @@ message FlowSchemaSpec { // `matchingPrecedence` is used to choose among the FlowSchemas that match a given request. The chosen // FlowSchema is among those with the numerically lowest (which we take to be logically highest) - // MatchingPrecedence. Each MatchingPrecedence value must be non-negative. - // Note that if the precedence is not specified or zero, it will be set to 1000 as default. + // MatchingPrecedence. Each MatchingPrecedence value must be ranged in [1,10000]. + // Note that if the precedence is not specified, it will be set to 1000 as default. // +optional optional int32 matchingPrecedence = 2; diff --git a/staging/src/k8s.io/api/flowcontrol/v1alpha1/types.go b/staging/src/k8s.io/api/flowcontrol/v1alpha1/types.go index 41073bdcb14..137f480735f 100644 --- a/staging/src/k8s.io/api/flowcontrol/v1alpha1/types.go +++ b/staging/src/k8s.io/api/flowcontrol/v1alpha1/types.go @@ -43,6 +43,11 @@ const ( PriorityLevelConfigurationConditionConcurrencyShared = "ConcurrencyShared" ) +// Constants used by api validation. +const ( + FlowSchemaMaxMatchingPrecedence int32 = 10000 +) + // +genclient // +genclient:nonNamespaced // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object @@ -88,8 +93,8 @@ type FlowSchemaSpec struct { PriorityLevelConfiguration PriorityLevelConfigurationReference `json:"priorityLevelConfiguration" protobuf:"bytes,1,opt,name=priorityLevelConfiguration"` // `matchingPrecedence` is used to choose among the FlowSchemas that match a given request. The chosen // FlowSchema is among those with the numerically lowest (which we take to be logically highest) - // MatchingPrecedence. Each MatchingPrecedence value must be non-negative. - // Note that if the precedence is not specified or zero, it will be set to 1000 as default. + // MatchingPrecedence. Each MatchingPrecedence value must be ranged in [1,10000]. + // Note that if the precedence is not specified, it will be set to 1000 as default. // +optional MatchingPrecedence int32 `json:"matchingPrecedence" protobuf:"varint,2,opt,name=matchingPrecedence"` // `distinguisherMethod` defines how to compute the flow distinguisher for requests that match this schema. diff --git a/staging/src/k8s.io/api/flowcontrol/v1alpha1/types_swagger_doc_generated.go b/staging/src/k8s.io/api/flowcontrol/v1alpha1/types_swagger_doc_generated.go index 08380a1b1c0..ffbee2e3a9c 100644 --- a/staging/src/k8s.io/api/flowcontrol/v1alpha1/types_swagger_doc_generated.go +++ b/staging/src/k8s.io/api/flowcontrol/v1alpha1/types_swagger_doc_generated.go @@ -73,7 +73,7 @@ func (FlowSchemaList) SwaggerDoc() map[string]string { var map_FlowSchemaSpec = map[string]string{ "": "FlowSchemaSpec describes how the FlowSchema's specification looks like.", "priorityLevelConfiguration": "`priorityLevelConfiguration` should reference a PriorityLevelConfiguration in the cluster. If the reference cannot be resolved, the FlowSchema will be ignored and marked as invalid in its status. Required.", - "matchingPrecedence": "`matchingPrecedence` is used to choose among the FlowSchemas that match a given request. The chosen FlowSchema is among those with the numerically lowest (which we take to be logically highest) MatchingPrecedence. Each MatchingPrecedence value must be non-negative. Note that if the precedence is not specified or zero, it will be set to 1000 as default.", + "matchingPrecedence": "`matchingPrecedence` is used to choose among the FlowSchemas that match a given request. The chosen FlowSchema is among those with the numerically lowest (which we take to be logically highest) MatchingPrecedence. Each MatchingPrecedence value must be ranged in [1,10000]. Note that if the precedence is not specified, it will be set to 1000 as default.", "distinguisherMethod": "`distinguisherMethod` defines how to compute the flow distinguisher for requests that match this schema. `nil` specifies that the distinguisher is disabled and thus will always be the empty string.", "rules": "`rules` describes which requests will match this flow schema. This FlowSchema matches a request if and only if at least one member of rules matches the request. if it is an empty slice, there will be no requests matching the FlowSchema.", }