-
Notifications
You must be signed in to change notification settings - Fork 40.6k
Consider allowing CEL validation of metadata.namespace field of embedded resource #122163
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
Comments
/sig api-machinery |
/triage accepted
The consideration behind it is mainly that we wanna metadata to be homogeneous across types. The alternative solution to this would be ValidatingAdmissionPolicy which will give you access to namespace. |
Yes, I could just use ValidatingAdmissionPolicy, but tbh if that's the solution then what's the point of this restriction on CRD level, if I can just validate whatever I want using VAP? Preferably if possible I'd like to have the source of those validation policies near the Go structs in my codebase (it would be the case if I had an access to namespace), and not "far" away in e.g helm chart in VAP, which might get de-synchronised with the fields in the CRD by accident. |
Proposal: Allow CEL Validation for metadata.namespace in CRD Embedded Resources Overview: Proposed Solution: Benefits: Stable Identities: Ensure stable identities for embedded resources, crucial for scenarios like multi-tenancy or cross-namespace resource management. Operational Efficiency: Empower users to maintain predictability and reliability in applications relying on stable identity configurations. Feasibility and Considerations: Implementation: Discuss the feasibility, considering impacts on workflows, backward compatibility, and implementation effort. Challenges: Acknowledge challenges and potential trade-offs, such as added complexity or dependencies. Addressing Concerns: Alternative Solutions: Discuss alternatives, including ValidatingAdmissionPolicy (VAP), highlighting pros and cons. Community Input: Encourage community feedback and diverse perspectives on the proposal. |
This does feel a bit quirky, given that apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: foos.example.com
spec:
group: example.com
versions:
- name: v1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
embedme:
type: object
x-kubernetes-embedded-resource: true
x-kubernetes-preserve-unknown-fields: true
required:
- metadata
properties:
apiVersion:
type: string
x-kubernetes-validations:
- rule: "self == oldSelf"
message: apiVersion is immutable
kind:
type: string
x-kubernetes-validations:
- rule: "self == oldSelf"
message: kind is immutable
metadata:
type: object
required:
- namespace
- name
properties:
name:
type: string
x-kubernetes-validations:
- rule: "self == oldSelf"
message: name is immutable
generateName:
type: string
namespace:
type: string
x-kubernetes-validations:
- rule: "self == oldSelf"
message: namespace is immutable
scope: Cluster
names:
plural: foos
singular: foo
kind: Foo This seems to work for embedded resources that must be namespaced. It's awkward for a couple reasons:
|
If I'm following, (1), (2) and (3) all result in sub-par validation compared with the root resource. I'd be very interested in seeing that improved. my notes: (1) - This seems like a bug. We wouldn't see it on the root because we have built-in immutability validation. Is this also a problem with OpenAPI value validations? (e.g. a regex rule or length rule)? |
@aerfio A workaround is to declare all the CEL rules "above" the embedded resource: apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: withembeddeds.stable.example.com
spec:
group: stable.example.com
versions:
- name: v1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
required:
- embedme
x-kubernetes-validations:
- rule: 'oldSelf.embedme.kind == self.embedme.kind'
- rule: 'oldSelf.embedme.apiVersion == self.embedme.apiVersion'
- rule: 'oldSelf.embedme.metadata.name == self.embedme.metadata.name'
- rule: 'has(self.embedme.metadata.__namespace__)'
- rule: 'oldSelf.embedme.metadata.__namespace__ == self.embedme.metadata.__namespace__'
properties:
embedme:
type: object
x-kubernetes-embedded-resource: true
x-kubernetes-preserve-unknown-fields: true
required:
- apiVersion
- kind
- metadata
properties:
apiVersion:
type: string
kind:
type: string
metadata:
type: object
required:
- namespace
- name
properties:
name:
type: string
generateName:
type: string
namespace:
type: string
scope: Namespaced
names:
plural: withembeddeds
singular: withembedded
kind: WithEmbedded Note that all the metadata fields must be explicitly declared.. I don't know if you get this with kubebuilder. Also, the exact validation rules will depend on:
My example assumes the embedded resource is required, namespace scoped, and uses name (not generateName). |
This issue has not been updated in over 1 year, and should be re-triaged. You can:
For more details on the triage process, see https://www.kubernetes.dev/docs/guide/issue-triage/ /remove-triage accepted |
/triage accepted |
This is also an issue I have been facing when building validations into the CRD, being unable to validate The use cases we see in multiple operators:
Created ValidationAdminissionPolicies also requires a level of permissions which we cannot give our users/operators, without concerns for escalating privileges for other resource types on the cluster. Controlling my own CRD allows us to restrict the variation rules to only the resources I own. I would echo @aerfio comment that it would be ideal to have full access to the |
But For example, my use- case is a CRD with a pointer field, so my CR could point to another CR of the same type (and I need to point by name. I can't use object reference, for multiple reasons), e.g. metadata:
name: a-name
namespace: a-namespace
...
spec:
...
pointer:
name: another-cr
namespace: some-namespace
... I want to prevent the option to point to self CR. I was trying to add this CEL rule, and got the same issue:
|
This is tricky. I can see the argument for being able to use namespace as an input for validation.
What I want to prevent is CRD authors declaring validation rules about what namespaces a custom resource can be created in. This should be done using ValidatingAdmissionPolicy. But once I provide namespace as and input to CRD validation rules, it becomes possible to do what I'm trying to prevent. I think it's best to ask that users that need to inspect namespace to write a ValidatingAdmissionPolicy to enforce that rule. |
What would you like to be added?
Some context for the issue below: I'm writing operator and generating CRD yaml using
controller-gen
I have a CRD which has a
runtime.RawExtension
field, its spec looks more or less like this:I'd like to restrict users of that CRD to be able to set the name/namespace/gvk of this embedded resource only during creation, much like with a real resource. I want it to have stable identity, which is not possible if any of those 4 fields are possible to be edited. To do this I can either write and maintain a webhook or add CEL validation to this field. I've actually managed to do this succesfully for metadata.name, apiVersion and kind fields, like here:
Generating CRD yaml using controller-gen resulted in:
Full CRD
And such a CRD is successfully accepted by the APIServer. Unfortunately, as documented in here, once I add any validation rule to the metadata.namespace field I get an error
All of that behaviour is currently matching both the docs and the implementation found in
kubernetes/staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/model/schemas.go
Lines 39 to 73 in 55f2bc1
My suggestion would be to also allow users to include custom CEL validation rules for namespace field for embedded resources, which is the only one left that currently prevents me from disallowing users of that CR from updating the identity of that embedded resource.
Initially I've thought that the
x-kubernetes-embedded-resource: true
would take care of this, as stated in this document, where it saysBUT it's not said what is validated. I've actually created a very simple CRD with only 1 embedded field to test it (repo here), and it seems like I'm able to edit any subfield I want:

(
kaf
==kubectl apply -f
)Slack discussion I started for this situation: https://kubernetes.slack.com/archives/C0EG7JC6T/p1698949573455489
Why is this needed?
Adding ability to validate metadata.namespace would allow me to create CRD which would embed other k8s resources with the guarantee that the identity of those resources stays stable for particular CR instance.
Following fields are already open to CEL validation:
Source: https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#validation-rules
The text was updated successfully, but these errors were encountered: