Skip to content

Commit

Permalink
feat: nodeclassref immutablility
Browse files Browse the repository at this point in the history
  • Loading branch information
jmdeal committed Nov 20, 2024
1 parent d8115a1 commit f298996
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 2 deletions.
9 changes: 9 additions & 0 deletions kwok/charts/crds/karpenter.sh_nodeclaims.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,21 @@ spec:
description: API version of the referent
pattern: ^[^/]*$
type: string
x-kubernetes-validations:
- message: group may not be empty
rule: self != ''
kind:
description: 'Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds"'
type: string
x-kubernetes-validations:
- message: kind may not be empty
rule: self != ''
name:
description: 'Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names'
type: string
x-kubernetes-validations:
- message: name may not be empty
rule: self != ''
required:
- group
- kind
Expand Down
14 changes: 14 additions & 0 deletions kwok/charts/crds/karpenter.sh_nodepools.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -232,17 +232,31 @@ spec:
description: API version of the referent
pattern: ^[^/]*$
type: string
x-kubernetes-validations:
- message: group may not be empty
rule: self != ''
kind:
description: 'Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds"'
type: string
x-kubernetes-validations:
- message: kind may not be empty
rule: self != ''
name:
description: 'Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names'
type: string
x-kubernetes-validations:
- message: name may not be empty
rule: self != ''
required:
- group
- kind
- name
type: object
x-kubernetes-validations:
- message: nodeClassRef.group is immutable
rule: self.group == oldSelf.group
- message: nodeClassRef.kind is immutable
rule: self.kind == oldSelf.kind
requirements:
description: Requirements are layered with GetLabels and applied to every node.
items:
Expand Down
9 changes: 9 additions & 0 deletions pkg/apis/crds/karpenter.sh_nodeclaims.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,21 @@ spec:
description: API version of the referent
pattern: ^[^/]*$
type: string
x-kubernetes-validations:
- message: group may not be empty
rule: self != ''
kind:
description: 'Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds"'
type: string
x-kubernetes-validations:
- message: kind may not be empty
rule: self != ''
name:
description: 'Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names'
type: string
x-kubernetes-validations:
- message: name may not be empty
rule: self != ''
required:
- group
- kind
Expand Down
14 changes: 14 additions & 0 deletions pkg/apis/crds/karpenter.sh_nodepools.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -231,17 +231,31 @@ spec:
description: API version of the referent
pattern: ^[^/]*$
type: string
x-kubernetes-validations:
- message: group may not be empty
rule: self != ''
kind:
description: 'Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds"'
type: string
x-kubernetes-validations:
- message: kind may not be empty
rule: self != ''
name:
description: 'Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names'
type: string
x-kubernetes-validations:
- message: name may not be empty
rule: self != ''
required:
- group
- kind
- name
type: object
x-kubernetes-validations:
- message: nodeClassRef.group is immutable
rule: self.group == oldSelf.group
- message: nodeClassRef.kind is immutable
rule: self.kind == oldSelf.kind
requirements:
description: Requirements are layered with GetLabels and applied to every node.
items:
Expand Down
3 changes: 3 additions & 0 deletions pkg/apis/v1/nodeclaim.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,15 @@ type ResourceRequirements struct {

type NodeClassReference struct {
// Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds"
// +kubebuilder:validation:XValidation:rule="self != ''",message="kind may not be empty"
// +required
Kind string `json:"kind"`
// Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names
// +kubebuilder:validation:XValidation:rule="self != ''",message="name may not be empty"
// +required
Name string `json:"name"`
// API version of the referent
// +kubebuilder:validation:XValidation:rule="self != ''",message="group may not be empty"
// +kubebuilder:validation:Pattern=`^[^/]*$`
// +required
Group string `json:"group"`
Expand Down
2 changes: 2 additions & 0 deletions pkg/apis/v1/nodepool.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,8 @@ type NodeClaimTemplateSpec struct {
// +required
Requirements []NodeSelectorRequirementWithMinValues `json:"requirements" hash:"ignore"`
// NodeClassRef is a reference to an object that defines provider specific configuration
// +kubebuilder:validation:XValidation:rule="self.group == oldSelf.group",message="nodeClassRef.group is immutable"
// +kubebuilder:validation:XValidation:rule="self.kind == oldSelf.kind",message="nodeClassRef.kind is immutable"
// +required
NodeClassRef *NodeClassReference `json:"nodeClassRef"`
// TerminationGracePeriod is the maximum duration the controller will wait before forcefully deleting the pods on a node, measured from when deletion is first initiated.
Expand Down
29 changes: 27 additions & 2 deletions pkg/apis/v1/nodepool_validation_cel_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,9 @@ var _ = Describe("CEL/Validation", func() {
Template: NodeClaimTemplate{
Spec: NodeClaimTemplateSpec{
NodeClassRef: &NodeClassReference{
Kind: "NodeClaim",
Name: "default",
Group: "karpenter.test.sh",
Kind: "TestNodeClass",
Name: "default",
},
Requirements: []NodeSelectorRequirementWithMinValues{
{
Expand Down Expand Up @@ -619,4 +620,28 @@ var _ = Describe("CEL/Validation", func() {
Expect(env.Client.Create(ctx, nodePool)).ToNot(Succeed())
})
})
Context("NodeClassRef", func() {
It("should fail to mutate group", func() {
Expect(env.Client.Create(ctx, nodePool)).To(Succeed())
nodePool.Spec.Template.Spec.NodeClassRef.Group = "karpenter.k8s.aws"
Expect(env.Client.Create(ctx, nodePool)).ToNot(Succeed())
})
It("should fail to mutate kind", func() {
Expect(env.Client.Create(ctx, nodePool)).To(Succeed())
nodePool.Spec.Template.Spec.NodeClassRef.Group = "EC2NodeClass"
Expect(env.Client.Create(ctx, nodePool)).ToNot(Succeed())
})
It("should fail if group is unset", func() {
nodePool.Spec.Template.Spec.NodeClassRef.Group = ""
Expect(env.Client.Create(ctx, nodePool)).ToNot(Succeed())
})
It("should fail if kind is unset", func() {
nodePool.Spec.Template.Spec.NodeClassRef.Kind = ""
Expect(env.Client.Create(ctx, nodePool)).ToNot(Succeed())
})
It("should fail if name is unset", func() {
nodePool.Spec.Template.Spec.NodeClassRef.Name = ""
Expect(env.Client.Create(ctx, nodePool)).ToNot(Succeed())
})
})
})

0 comments on commit f298996

Please sign in to comment.