-
Notifications
You must be signed in to change notification settings - Fork 33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
AP Defaults #503
AP Defaults #503
Conversation
api/v1beta2/authpolicy_types.go
Outdated
// Defaults define explicit default values for this policy and for policies inheriting this policy. | ||
// Defaults are mutually exclusive with implicit defaults defined by CommonSpec. | ||
// +optional | ||
Defaults *CommonSpec `json:"defaults"` | ||
|
||
// CommonSpec defines implicit default values for this policy and for policies inheriting this policy. | ||
// CommonSpec is mutually exclusive with explicit defaults defined by Defaults. | ||
CommonSpec `json:""` | ||
} | ||
|
||
// CommonSpec contains common shared fields for defaults and overrides | ||
type CommonSpec struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This gives issues with CEL due to the cost of route selector validation is and size of the CRD
The CustomResourceDefinition "authpolicies.kuadrant.io" is invalid:
* metadata.annotations: Too long: must have at most 262144 bytes
* spec.validation.openAPIV3Schema.properties[spec].properties[rules].properties[authentication].additionalProperties.properties[routeSelectors].items.properties[matches].items.properties[path].x-kubernetes-validations[10].rule: Forbidden: contributed to estimated rule cost total exceeding cost limit for entire OpenAPIv3 schema
* spec.validation.openAPIV3Schema.properties[spec].properties[rules].properties[authorization].additionalProperties.properties[routeSelectors].items.properties[matches].items.properties[path].x-kubernetes-validations[10].rule: Forbidden: contributed to estimated rule cost total exceeding cost limit for entire OpenAPIv3 schema
* spec.validation.openAPIV3Schema.properties[spec].properties[rules].properties[callbacks].additionalProperties.properties[routeSelectors].items.properties[matches].items.properties[path].x-kubernetes-validations[10].rule: Forbidden: contributed to estimated rule cost total exceeding cost limit for entire OpenAPIv3 schema
* spec.validation.openAPIV3Schema.properties[spec].properties[rules].properties[metadata].additionalProperties.properties[routeSelectors].items.properties[matches].items.properties[path].x-kubernetes-validations[10].rule: Forbidden: contributed to estimated rule cost total exceeding cost limit for entire OpenAPIv3 schema
* spec.validation.openAPIV3Schema: Forbidden: x-kubernetes-validations estimated rule cost total for entire OpenAPIv3 schema exceeds budget by factor of 1.7x (try simplifying the rule, or adding maxItems, maxProperties, and maxLength where arrays, maps, and strings are declared)
make: *** [install] Error 1
So we might want to rethink of whether we truely want the 2 pathways to achieving defaults 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a workaround at 6a01a4b decreasing the max number of route selectors allowed, but would likely hit this problem again for overrides also which would decrease this number again
909a1cb
to
2798ac1
Compare
6c4decc
to
b4d066d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Verification worked as expected. Unsure what the best manual verification steps are for the CEL expression that have being add.
Added a couple of comments.
@@ -57,7 +57,7 @@ type CommonAuthRuleSpec struct { | |||
// At least one selected HTTPRoute rule must match to trigger the auth rule. | |||
// If no route selectors are specified, the auth rule will be evaluated at all requests to the protected routes. | |||
// +optional | |||
// +kubebuilder:validation:MaxItems=15 | |||
// +kubebuilder:validation:MaxItems=8 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need any test to cover this being changed in the future, as it was reduced from 15 to 8?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, can add a test. Though, I'm expecting this value to decrease again when the overrides field is added in #464
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool, and thinking out loud. If we need to increase that number in the future, is the workaround to create a webhook to do the validation and drop the use of the CEL?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added integration test for this.
I don't think just simply switching to using validation webhook would work, as I believe this more so relates to using a slice of RouteSelectors
that the fields itself also have CEL validation for and how frequently we have this slice of RouteSelectors
in the various structs used within the CRD. This will fail the CEL cost estimation when applying the CRD even if switch to using a validating webhook 🤔
kuadrant-operator/api/v1beta2/route_selectors.go
Lines 13 to 24 in 4f6a138
type RouteSelector struct { | |
// Hostnames defines a set of hostname that should match against the HTTP Host header to select a HTTPRoute to process the request | |
// https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec | |
// +optional | |
Hostnames []gatewayapiv1.Hostname `json:"hostnames,omitempty"` | |
// Matches define conditions used for matching the rule against incoming HTTP requests. | |
// https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec | |
// +optional | |
// +kubebuilder:validation:MaxItems=8 | |
Matches []gatewayapiv1.HTTPRouteMatch `json:"matches,omitempty"` | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's because we're importing Gateway API types and, with those, their CEL validation as well.
I guess our best options to avoid this hard limit are:
- wait for Adding GEP-995 for support for named route rules kubernetes-sigs/gateway-api#2593 to be implemented and then simplify the route selectors
- redefine the HTTPRouteMatch types ourselves without the validation – we could do this because the validation that matters is the one enforced on the HTTPRoute, not on the policy; on the policy, the only consequence of an "invalid" route selector is that the selector will not select any route rule.
controllers/authpolicy_authconfig.go
Outdated
@@ -112,39 +112,39 @@ func (r *AuthPolicyReconciler) desiredAuthConfig(ctx context.Context, ap *api.Au | |||
authConfig.Spec.Hosts = hosts | |||
|
|||
// named patterns | |||
if namedPatterns := ap.Spec.NamedPatterns; len(namedPatterns) > 0 { | |||
if namedPatterns := ap.GetNamedPatterns(); len(namedPatterns) > 0 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a thought/concern, which I am not sure what the best resolution is. There is nothing stop someone from accessing Spec.NamedPatterns
directly. This could lead to errors later. One way would be to force access through methods by making the fields in the Spec private. In this case the methods would want to be on the Spec struct and not the AP struct. Access would then look like ap.Spec.GetNamedPatterns()
.
This would need to apply to all data fields in the Spec and not just the NamedPatterns
. It should also apply to the spec in #456.
What do you think? Personal if I have access to the fields of a struct at some point I will access them directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a thought/concern, which I am not sure what the best resolution is. There is nothing stop someone from accessing
Spec.NamedPatterns
directly. This could lead to errors later. One way would be to force access through methods by making the fields in the Spec private. In this case the methods would want to be on the Spec struct and not the AP struct. Access would then look likeap.Spec.GetNamedPatterns()
.This would need to apply to all data fields in the Spec and not just the
NamedPatterns
. It should also apply to the spec in #456.
Hmm, I dont think this will quite work as intended. If we make fields private / not exported, I guess we need setters for all the fields also, while also having setters for the defaults fields. The will work for using the struct via code.
The other one is since the field is not exported, the json field will not be available via kubectl get policy x -o json
commands which I think makes this not viable unless I'm missing something.
What do you think? Personal if I have access to the fields of a struct at some point I will access them directly.
Yeah, unfortunately I think is an artefact of having multiple pathways of achieving the same result. I guess the assumption is that if people are acessing the fields directly via code, they know which pathway they are using, either spec.X
or spec.defaults.x
but the getters will be the best way to get the data without needing to know which pathway is used
@@ -161,13 +184,13 @@ type AuthPolicySpec struct { | |||
|
|||
// The auth rules of the policy. | |||
// See Authorino's AuthConfig CRD for more details. | |||
AuthScheme AuthSchemeSpec `json:"rules,omitempty"` | |||
AuthScheme *AuthSchemeSpec `json:"rules,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Switched to pointer so that this will not show on json spec
as empty object {}
when empty which would be a bit confusing to a user, especially if spec.defaults
is used instead 🤔 Also makes the mutual exclusive CEL rule a bit easier by switching to pointer
commonSpec := ap.Spec.CommonSpec() | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's no nil
check for AuthScheme
here as this function is only called from r.desiredAuthConfig()
which has been updated with this nil
check for AuthScheme
. This function will not be called in this case
@@ -406,14 +406,15 @@ kind-load-bundle: ## Load image to local cluster | |||
##@ Deployment | |||
|
|||
install: manifests kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config. | |||
$(KUSTOMIZE) build config/crd | kubectl apply -f - | |||
# Use server side apply, otherwise will hit into this issue https://medium.com/pareture/kubectl-install-crd-failed-annotations-too-long-2ebc91b40c7d | |||
$(KUSTOMIZE) build config/crd | kubectl apply --server-side -f - |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not quite sure will this be an issue for OLM upgrading CRDs. I'm wishful that this will not be an issue for OLM, and this is just a local issue 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The AuthPolicy CRD itself has reached ~600 Kb already with this change. IIRC, by default, the maximum request size accepted by etcd is 1.5 Mb – actual value size between 2 Mb (default) and 8 Mb (recommended maximum.)
| `rules` | [AuthScheme](#authscheme) | No | Implicit default authentication/authorization rules | | ||
| `routeSelectors` | [][RouteSelector](route-selectors.md#routeselector) | No | List of implicit default selectors of HTTPRouteRules whose matching rules activate the policy. At least one HTTPRouteRule must be selected to activate the policy. If omitted, all HTTPRouteRules of the targeted HTTPRoute activate the policy. Do not use it in policies targeting a Gateway. | | ||
| `patterns` | Map<String: [NamedPattern](#namedpattern)> | No | Implicit default named patterns of lists of `selector`, `operator` and `value` tuples, to be reused in `when` conditions and pattern-matching authorization rules. | | ||
| `when` | [][PatternExpressionOrRef](https://docs.kuadrant.io/authorino/docs/features/#common-feature-conditions-when) | No | List of implicit default additional dynamic conditions (expressions) to activate the policy. Use it for filtering attributes that cannot be expressed in the targeted HTTPRoute's `spec.hostnames` and `spec.rules.matches` fields, or when targeting a Gateway. | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The when
conditions at this level will be a problem when we get to Tier 2 of D/O and introduce constraints.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Nice work, @KevFan!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM - Happy with changes, all my comments and concerns were addressed.
* feat: ap default field * refactor: Getters for common shared default fields * workaround: reduce route selector length & use server side apply * refactor: use explicit default in AP integration tests * refactor: AP CEL validation * refactor: AuthPolicyCommonSpec * docs: update AuthPolicy doc with defaults field * refactor: remove unneccessary getters * refactor: reset number of root level route selectors & add integration tests * refactor: remove debug log from new AP route selector integration tests
Description
Closes: #462
Adds the
defaults
field to the AuthPolicy spec. This field is mutually exclusive with the pre-existing fields for defining auth rules in the bare spec.Verification
The explicit default path is already tests by integration tests but it you want to verify manually: