Skip to content

Commit b02fa6e

Browse files
committed
fix: add CEL validation rule to require one of volume configs
1 parent 861acfe commit b02fa6e

File tree

6 files changed

+136
-0
lines changed

6 files changed

+136
-0
lines changed

api/v1alpha1/aws_node_types.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ type AMILookup struct {
114114
BaseOS string `json:"baseOS,omitempty"`
115115
}
116116

117+
// +kubebuilder:validation:XValidation:rule="has(self.root) || size(self.nonroot) > 0",message="either root or nonroot must be specified"
117118
type AWSVolumes struct {
118119
// Configuration options for the root storage volume.
119120
// +kubebuilder:validation:Optional

api/v1alpha1/crds/caren.nutanix.com_awsclusterconfigs.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,9 @@ spec:
498498
type: string
499499
type: object
500500
type: object
501+
x-kubernetes-validations:
502+
- message: either root or nonroot must be specified
503+
rule: has(self.root) || size(self.nonroot) > 0
501504
type: object
502505
nodeRegistration:
503506
default: {}

api/v1alpha1/crds/caren.nutanix.com_awsworkernodeconfigs.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,9 @@ spec:
200200
type: string
201201
type: object
202202
type: object
203+
x-kubernetes-validations:
204+
- message: either root or nonroot must be specified
205+
rule: has(self.root) || size(self.nonroot) > 0
203206
type: object
204207
nodeRegistration:
205208
default: {}

api/v1alpha1/crds/caren.nutanix.com_eksworkernodeconfigs.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,9 @@ spec:
200200
type: string
201201
type: object
202202
type: object
203+
x-kubernetes-validations:
204+
- message: either root or nonroot must be specified
205+
rule: has(self.root) || size(self.nonroot) > 0
203206
type: object
204207
taints:
205208
description: Taints specifies the taints the Node API object should

pkg/handlers/aws/mutation/volumes/variables_test.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,5 +53,72 @@ func TestVariableValidation(t *testing.T) {
5353
},
5454
},
5555
},
56+
capitest.VariableTestDef{
57+
Name: "Root volume only",
58+
Vals: v1alpha1.AWSClusterConfigSpec{
59+
ControlPlane: &v1alpha1.AWSControlPlaneSpec{
60+
AWS: &v1alpha1.AWSControlPlaneNodeSpec{
61+
AWSGenericNodeSpec: v1alpha1.AWSGenericNodeSpec{
62+
Volumes: &v1alpha1.AWSVolumes{
63+
Root: &v1alpha1.AWSVolume{
64+
Size: 100,
65+
Type: capav1.VolumeTypeGP3,
66+
},
67+
},
68+
},
69+
},
70+
},
71+
},
72+
},
73+
capitest.VariableTestDef{
74+
Name: "Non-root volumes only",
75+
Vals: v1alpha1.AWSClusterConfigSpec{
76+
ControlPlane: &v1alpha1.AWSControlPlaneSpec{
77+
AWS: &v1alpha1.AWSControlPlaneNodeSpec{
78+
AWSGenericNodeSpec: v1alpha1.AWSGenericNodeSpec{
79+
Volumes: &v1alpha1.AWSVolumes{
80+
NonRoot: []v1alpha1.AWSVolume{
81+
{
82+
DeviceName: "/dev/sdf",
83+
Size: 200,
84+
Type: capav1.VolumeTypeGP3,
85+
},
86+
},
87+
},
88+
},
89+
},
90+
},
91+
},
92+
},
93+
capitest.VariableTestDef{
94+
Name: "Error when neither root nor non-root volumes",
95+
Vals: v1alpha1.AWSClusterConfigSpec{
96+
ControlPlane: &v1alpha1.AWSControlPlaneSpec{
97+
AWS: &v1alpha1.AWSControlPlaneNodeSpec{
98+
AWSGenericNodeSpec: v1alpha1.AWSGenericNodeSpec{
99+
Volumes: &v1alpha1.AWSVolumes{
100+
// Both Root and NonRoot are nil/empty
101+
},
102+
},
103+
},
104+
},
105+
},
106+
ExpectError: true,
107+
},
108+
capitest.VariableTestDef{
109+
Name: "Error when empty non-root volumes array",
110+
Vals: v1alpha1.AWSClusterConfigSpec{
111+
ControlPlane: &v1alpha1.AWSControlPlaneSpec{
112+
AWS: &v1alpha1.AWSControlPlaneNodeSpec{
113+
AWSGenericNodeSpec: v1alpha1.AWSGenericNodeSpec{
114+
Volumes: &v1alpha1.AWSVolumes{
115+
NonRoot: []v1alpha1.AWSVolume{},
116+
},
117+
},
118+
},
119+
},
120+
},
121+
ExpectError: true,
122+
},
56123
)
57124
}

pkg/handlers/eks/mutation/volumes/variables_test.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,5 +51,64 @@ func TestVariableValidation(t *testing.T) {
5151
},
5252
},
5353
},
54+
capitest.VariableTestDef{
55+
Name: "Root volume only",
56+
Vals: v1alpha1.EKSWorkerNodeConfigSpec{
57+
EKS: &v1alpha1.AWSWorkerNodeSpec{
58+
AWSGenericNodeSpec: v1alpha1.AWSGenericNodeSpec{
59+
Volumes: &v1alpha1.AWSVolumes{
60+
Root: &v1alpha1.AWSVolume{
61+
Size: 100,
62+
Type: capav1.VolumeTypeGP3,
63+
},
64+
},
65+
},
66+
},
67+
},
68+
},
69+
capitest.VariableTestDef{
70+
Name: "Non-root volumes only",
71+
Vals: v1alpha1.EKSWorkerNodeConfigSpec{
72+
EKS: &v1alpha1.AWSWorkerNodeSpec{
73+
AWSGenericNodeSpec: v1alpha1.AWSGenericNodeSpec{
74+
Volumes: &v1alpha1.AWSVolumes{
75+
NonRoot: []v1alpha1.AWSVolume{
76+
{
77+
DeviceName: "/dev/sdf",
78+
Size: 200,
79+
Type: capav1.VolumeTypeGP3,
80+
},
81+
},
82+
},
83+
},
84+
},
85+
},
86+
},
87+
capitest.VariableTestDef{
88+
Name: "Error when neither root nor non-root volumes",
89+
Vals: v1alpha1.EKSWorkerNodeConfigSpec{
90+
EKS: &v1alpha1.AWSWorkerNodeSpec{
91+
AWSGenericNodeSpec: v1alpha1.AWSGenericNodeSpec{
92+
Volumes: &v1alpha1.AWSVolumes{
93+
// Both Root and NonRoot are nil/empty
94+
},
95+
},
96+
},
97+
},
98+
ExpectError: true,
99+
},
100+
capitest.VariableTestDef{
101+
Name: "Error when empty non-root volumes array",
102+
Vals: v1alpha1.EKSWorkerNodeConfigSpec{
103+
EKS: &v1alpha1.AWSWorkerNodeSpec{
104+
AWSGenericNodeSpec: v1alpha1.AWSGenericNodeSpec{
105+
Volumes: &v1alpha1.AWSVolumes{
106+
NonRoot: []v1alpha1.AWSVolume{},
107+
},
108+
},
109+
},
110+
},
111+
ExpectError: true,
112+
},
54113
)
55114
}

0 commit comments

Comments
 (0)