Skip to content

Commit 67e1fb2

Browse files
authored
feat: Add cluster name check for ocicluster webhook (#143)
1 parent 78a3a94 commit 67e1fb2

File tree

2 files changed

+90
-17
lines changed

2 files changed

+90
-17
lines changed

api/v1beta1/ocicluster_webhook.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ package v1beta1
2121

2222
import (
2323
"fmt"
24+
"regexp"
2425

2526
apierrors "k8s.io/apimachinery/pkg/api/errors"
2627
"k8s.io/apimachinery/pkg/runtime"
@@ -37,6 +38,12 @@ var (
3738
_ webhook.Validator = &OCICluster{}
3839
)
3940

41+
const (
42+
// can't use: \/"'[]:|<>+=;,.?*@&, Can't start with underscore. Can't end with period or hyphen.
43+
// not using . in the name to avoid issues when the name is part of DNS name.
44+
clusterNameRegex = `^[a-z0-9][a-z0-9-]{0,42}[a-z0-9]$`
45+
)
46+
4047
// +kubebuilder:webhook:verbs=create;update,path=/validate-infrastructure-cluster-x-k8s-io-v1beta1-ocicluster,mutating=false,failurePolicy=fail,matchPolicy=Equivalent,groups=infrastructure.cluster.x-k8s.io,resources=ociclusters,versions=v1beta1,name=validation.ocicluster.infrastructure.cluster.x-k8s.io,sideEffects=None,admissionReviewVersions=v1beta1
4148
// +kubebuilder:webhook:verbs=create;update,path=/mutate-infrastructure-cluster-x-k8s-io-v1beta1-ocicluster,mutating=true,failurePolicy=fail,matchPolicy=Equivalent,groups=infrastructure.cluster.x-k8s.io,resources=ociclusters,versions=v1beta1,name=default.ocicluster.infrastructure.cluster.x-k8s.io,sideEffects=None,admissionReviewVersions=v1;v1beta1
4249

@@ -115,6 +122,7 @@ func (c *OCICluster) validate(old *OCICluster) field.ErrorList {
115122
}
116123

117124
allErrs = append(allErrs, validateNetworkSpec(c.Spec.NetworkSpec, oldNetworkSpec, field.NewPath("spec").Child("networkSpec"))...)
125+
allErrs = append(allErrs, c.validateClusterName()...)
118126

119127
if len(c.Spec.CompartmentId) <= 0 {
120128
allErrs = append(
@@ -148,3 +156,18 @@ func (c *OCICluster) validate(old *OCICluster) field.ErrorList {
148156

149157
return allErrs
150158
}
159+
160+
// validateClusterName validates the cluster name
161+
func (c *OCICluster) validateClusterName() field.ErrorList {
162+
var allErrs field.ErrorList
163+
164+
if success, _ := regexp.MatchString(clusterNameRegex, c.Name); !success {
165+
allErrs = append(allErrs, field.Invalid(field.NewPath("metadata").Child("Name"), c.Name,
166+
fmt.Sprintf("Cluster Name doesn't match regex %s, can contain only lowercase alphanumeric characters and '-', must start/end with an alphanumeric character",
167+
clusterNameRegex)))
168+
}
169+
if len(allErrs) == 0 {
170+
return nil
171+
}
172+
return allErrs
173+
}

api/v1beta1/ocicluster_webhook_test.go

Lines changed: 67 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ func TestOCICluster_ValidateCreate(t *testing.T) {
7777
Role: "not-control-plane",
7878
},
7979
}
80+
goodClusterName := "test-cluster"
81+
badClusterName := "bad.cluster"
8082

8183
tests := []struct {
8284
name string
@@ -87,7 +89,9 @@ func TestOCICluster_ValidateCreate(t *testing.T) {
8789
{
8890
name: "shouldn't allow spaces in region",
8991
c: &OCICluster{
90-
ObjectMeta: metav1.ObjectMeta{},
92+
ObjectMeta: metav1.ObjectMeta{
93+
Name: goodClusterName,
94+
},
9195
Spec: OCIClusterSpec{
9296
Region: "us city 1",
9397
},
@@ -98,7 +102,9 @@ func TestOCICluster_ValidateCreate(t *testing.T) {
98102
{
99103
name: "shouldn't allow bad CompartmentId",
100104
c: &OCICluster{
101-
ObjectMeta: metav1.ObjectMeta{},
105+
ObjectMeta: metav1.ObjectMeta{
106+
Name: goodClusterName,
107+
},
102108
Spec: OCIClusterSpec{
103109
CompartmentId: "badocid",
104110
},
@@ -109,16 +115,20 @@ func TestOCICluster_ValidateCreate(t *testing.T) {
109115
{
110116
name: "shouldn't allow blank CompartmentId",
111117
c: &OCICluster{
112-
ObjectMeta: metav1.ObjectMeta{},
113-
Spec: OCIClusterSpec{},
118+
ObjectMeta: metav1.ObjectMeta{
119+
Name: goodClusterName,
120+
},
121+
Spec: OCIClusterSpec{},
114122
},
115123
errorMgsShouldContain: "compartmentId",
116124
expectErr: true,
117125
},
118126
{
119127
name: "shouldn't allow bad vcn cider",
120128
c: &OCICluster{
121-
ObjectMeta: metav1.ObjectMeta{},
129+
ObjectMeta: metav1.ObjectMeta{
130+
Name: goodClusterName,
131+
},
122132
Spec: OCIClusterSpec{
123133
NetworkSpec: NetworkSpec{
124134
Vcn: VCN{
@@ -133,7 +143,9 @@ func TestOCICluster_ValidateCreate(t *testing.T) {
133143
{
134144
name: "shouldn't allow blank OCIResourceIdentifier",
135145
c: &OCICluster{
136-
ObjectMeta: metav1.ObjectMeta{},
146+
ObjectMeta: metav1.ObjectMeta{
147+
Name: goodClusterName,
148+
},
137149
Spec: OCIClusterSpec{
138150
CompartmentId: "ocid",
139151
},
@@ -144,7 +156,9 @@ func TestOCICluster_ValidateCreate(t *testing.T) {
144156
{
145157
name: "shouldn't allow subnet cidr outside of vcn cidr",
146158
c: &OCICluster{
147-
ObjectMeta: metav1.ObjectMeta{},
159+
ObjectMeta: metav1.ObjectMeta{
160+
Name: goodClusterName,
161+
},
148162
Spec: OCIClusterSpec{
149163
NetworkSpec: NetworkSpec{
150164
Vcn: VCN{
@@ -160,7 +174,9 @@ func TestOCICluster_ValidateCreate(t *testing.T) {
160174
{
161175
name: "should allow empty subnet cidr",
162176
c: &OCICluster{
163-
ObjectMeta: metav1.ObjectMeta{},
177+
ObjectMeta: metav1.ObjectMeta{
178+
Name: goodClusterName,
179+
},
164180
Spec: OCIClusterSpec{
165181
CompartmentId: "ocid",
166182
OCIResourceIdentifier: "uuid",
@@ -177,7 +193,9 @@ func TestOCICluster_ValidateCreate(t *testing.T) {
177193
{
178194
name: "shouldn't allow subnet bad cidr format",
179195
c: &OCICluster{
180-
ObjectMeta: metav1.ObjectMeta{},
196+
ObjectMeta: metav1.ObjectMeta{
197+
Name: goodClusterName,
198+
},
181199
Spec: OCIClusterSpec{
182200
NetworkSpec: NetworkSpec{
183201
Vcn: VCN{
@@ -193,7 +211,9 @@ func TestOCICluster_ValidateCreate(t *testing.T) {
193211
{
194212
name: "shouldn't allow subnet cidr outside of vcn cidr",
195213
c: &OCICluster{
196-
ObjectMeta: metav1.ObjectMeta{},
214+
ObjectMeta: metav1.ObjectMeta{
215+
Name: goodClusterName,
216+
},
197217
Spec: OCIClusterSpec{
198218
NetworkSpec: NetworkSpec{
199219
Vcn: VCN{
@@ -209,7 +229,9 @@ func TestOCICluster_ValidateCreate(t *testing.T) {
209229
{
210230
name: "shouldn't allow subnet role outside of pre-defined roles",
211231
c: &OCICluster{
212-
ObjectMeta: metav1.ObjectMeta{},
232+
ObjectMeta: metav1.ObjectMeta{
233+
Name: goodClusterName,
234+
},
213235
Spec: OCIClusterSpec{
214236
NetworkSpec: NetworkSpec{
215237
Vcn: VCN{
@@ -222,10 +244,32 @@ func TestOCICluster_ValidateCreate(t *testing.T) {
222244
errorMgsShouldContain: "subnet role invalid",
223245
expectErr: true,
224246
},
247+
{
248+
name: "shouldn't allow bad cluster names",
249+
c: &OCICluster{
250+
ObjectMeta: metav1.ObjectMeta{
251+
Name: badClusterName,
252+
},
253+
Spec: OCIClusterSpec{
254+
CompartmentId: "ocid",
255+
OCIResourceIdentifier: "uuid",
256+
NetworkSpec: NetworkSpec{
257+
Vcn: VCN{
258+
CIDR: "10.0.0.0/16",
259+
Subnets: emptySubnetName,
260+
},
261+
},
262+
},
263+
},
264+
errorMgsShouldContain: "Cluster Name doesn't match regex",
265+
expectErr: true,
266+
},
225267
{
226268
name: "should allow empty subnet name",
227269
c: &OCICluster{
228-
ObjectMeta: metav1.ObjectMeta{},
270+
ObjectMeta: metav1.ObjectMeta{
271+
Name: goodClusterName,
272+
},
229273
Spec: OCIClusterSpec{
230274
CompartmentId: "ocid",
231275
OCIResourceIdentifier: "uuid",
@@ -242,7 +286,9 @@ func TestOCICluster_ValidateCreate(t *testing.T) {
242286
{
243287
name: "shouldn't allow bad NSG egress cidr",
244288
c: &OCICluster{
245-
ObjectMeta: metav1.ObjectMeta{},
289+
ObjectMeta: metav1.ObjectMeta{
290+
Name: goodClusterName,
291+
},
246292
Spec: OCIClusterSpec{
247293
NetworkSpec: NetworkSpec{
248294
Vcn: VCN{
@@ -264,7 +310,9 @@ func TestOCICluster_ValidateCreate(t *testing.T) {
264310
{
265311
name: "shouldn't allow bad NSG ingress cidr",
266312
c: &OCICluster{
267-
ObjectMeta: metav1.ObjectMeta{},
313+
ObjectMeta: metav1.ObjectMeta{
314+
Name: goodClusterName,
315+
},
268316
Spec: OCIClusterSpec{
269317
NetworkSpec: NetworkSpec{
270318
Vcn: VCN{
@@ -286,7 +334,9 @@ func TestOCICluster_ValidateCreate(t *testing.T) {
286334
{
287335
name: "shouldn't allow bad NSG role",
288336
c: &OCICluster{
289-
ObjectMeta: metav1.ObjectMeta{},
337+
ObjectMeta: metav1.ObjectMeta{
338+
Name: goodClusterName,
339+
},
290340
Spec: OCIClusterSpec{
291341
NetworkSpec: NetworkSpec{
292342
Vcn: VCN{
@@ -304,7 +354,7 @@ func TestOCICluster_ValidateCreate(t *testing.T) {
304354
name: "should allow blank region",
305355
c: &OCICluster{
306356
ObjectMeta: metav1.ObjectMeta{
307-
Name: "cluster-name",
357+
Name: goodClusterName,
308358
},
309359
Spec: OCIClusterSpec{
310360
Region: "",
@@ -324,7 +374,7 @@ func TestOCICluster_ValidateCreate(t *testing.T) {
324374
name: "should succeed",
325375
c: &OCICluster{
326376
ObjectMeta: metav1.ObjectMeta{
327-
Name: "cluster-name",
377+
Name: goodClusterName,
328378
},
329379
Spec: OCIClusterSpec{
330380
Region: "us-lexington-1",

0 commit comments

Comments
 (0)