Skip to content

Commit

Permalink
fix: add name validation for custom resources
Browse files Browse the repository at this point in the history
This propagates the label constraints of Linode resources to their associated
CustomResourceDefinitions via the Kubernetes Validation Rules feature. When a
custom resource is created, the Kubernetes object name is validated against the
label constraints of its backing Linode resources. This allows CAPL-managed
resources to maintain a human-readable naming scheme between its Kubernetes
representation and the backing Linode implementation.

Validation rules are implemented via Kustomize JSON patches due to limitations
with Kubebuilder and Strategic Merge Patching with CRDs in Kubernetes.

See:
- https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#validation-rules
- https://www.github.com/kubernetes/kubernetes/issues/74620
- https://www.github.com/kubernetes-sigs/kubebuilder/issues/1074
- https://www.github.com/kubernetes/kubernetes/issues/113223
  • Loading branch information
cbang-akamai committed Mar 28, 2024
1 parent 1bad604 commit d76d945
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 0 deletions.
21 changes: 21 additions & 0 deletions config/crd/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,27 @@ patches:
#- path: patches/cainjection_in_linodeobjectstoragebuckets.yaml
#+kubebuilder:scaffold:crdkustomizecainjectionpatch

# [VALIDATION]
# patches here are for additional validation for each CRD
- target:
group: apiextensions.k8s.io
version: v1
kind: CustomResourceDefinition
name: linodeclusters.infrastructure.cluster.x-k8s.io
path: patches/validation_in_linodeclusters.yaml
- target:
group: apiextensions.k8s.io
version: v1
kind: CustomResourceDefinition
name: linodemachines.infrastructure.cluster.x-k8s.io
path: patches/validation_in_linodemachines.yaml
- target:
group: apiextensions.k8s.io
version: v1
kind: CustomResourceDefinition
name: linodevpcs.infrastructure.cluster.x-k8s.io
path: patches/validation_in_linodevpcs.yaml

# the following config is for teaching kustomize how to do kustomization for CRDs.
configurations:
- kustomizeconfig.yaml
11 changes: 11 additions & 0 deletions config/crd/patches/validation_in_linodeclusters.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# The following patch adds additional constraints after the built-in name validation for the CRD
- op: add
path: /spec/versions/0/schema/openAPIV3Schema/properties/metadata/properties
value:
name:
type: string
x-kubernetes-validations:
- rule: 3 <= size(self) && size(self) <= 32
message: >-
custom validation:
linode nodebalancer: labels must be between 3..32 characters
26 changes: 26 additions & 0 deletions config/crd/patches/validation_in_linodemachines.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# The following patch adds additional constraints after the built-in name validation for the CRD
- op: add
path: /spec/versions/0/schema/openAPIV3Schema/properties/metadata/properties
value:
name:
type: string
x-kubernetes-validations:
- rule: 3 <= size(self) && size(self) <= 64
message: >-
custom validation:
linode instance: labels must be between 3..64 characters
- rule: self.matches('^[[:alnum:]]([-_.[:alnum:]]+[[:alnum:]])*$')
message: >-
custom validation:
linode instance: labels:
must begin and end with an alphanumeric character,
may only consist of alphanumeric characters, hyphens (-), underscores (_) or periods (.),
cannot have two hyphens (--), underscores (__) or periods (..) in a row,
regex used for validation is: '^[[:alnum:]]([-_.[:alnum:]]+[[:alnum:]])*$',
see: https://www.linode.com/docs/api/linode-instances/#linode-create
# TODO: Consider combining this into the regex above to minimize time complexity
# See: https://github.com/google/cel-spec/blob/master/doc/langdef.md#time-complexity
- rule: "!(self.contains('--') || self.contains('__') || self.contains('..'))"
message: >-
custom validation:
linode instance: labels cannot have two hyphens (--), underscores (__) or periods (..) in a row
25 changes: 25 additions & 0 deletions config/crd/patches/validation_in_linodevpcs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# The following patch adds additional constraints after the built-in name validation for the CRD
- op: add
path: /spec/versions/0/schema/openAPIV3Schema/properties/metadata/properties
value:
name:
type: string
x-kubernetes-validations:
- rule: 1 <= size(self) && size(self) <= 64
message: >-
custom validation:
linode vpc: labels must be between 3..64 characters
- rule: self.matches('^[-[:alnum:]]*$')
message: >-
custom validation:
linode vpc: labels:
can only contain ASCII letters, numbers, and hyphens (-),
cannot have two consecutive hyphens (--),
regex used for validation is: '^[-[:alnum:]]*$',
see: https://www.linode.com/docs/api/vpcs/#vpc-create
# TODO: Consider combining this into the regex above to minimize time complexity
# See: https://github.com/google/cel-spec/blob/master/doc/langdef.md#time-complexity
- rule: "!self.contains('--')"
message: >-
custom validation:
linode vpc: labels cannot have two consecutive hyphens (--)

0 comments on commit d76d945

Please sign in to comment.