Skip to content

Commit 7580343

Browse files
committed
Imporove ip address validation
Signed-off-by: peppi-lotta <[email protected]>
1 parent b5b6a3b commit 7580343

File tree

7 files changed

+737
-22
lines changed

7 files changed

+737
-22
lines changed

internal/webhooks/v1alpha1/ipaddress_webhook.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,28 @@ func (webhook *IPAddress) ValidateCreate(_ context.Context, obj runtime.Object)
8686
"cannot be empty",
8787
),
8888
)
89+
} else if validateIP(c.Spec.Address) != nil {
90+
allErrs = append(allErrs,
91+
field.Invalid(
92+
field.NewPath("spec", "address"),
93+
c.Spec.Address,
94+
"is not a valid IP address",
95+
),
96+
)
8997
}
9098

99+
// Validate requested IP address if present in annotations (for CAPI claims)
100+
if requestedIP, ok := c.ObjectMeta.Annotations["ipAddress"]; ok && requestedIP != "" {
101+
if validateIP(ipamv1.IPAddressStr(requestedIP)) != nil {
102+
allErrs = append(allErrs,
103+
field.Invalid(
104+
field.NewPath("metadata", "annotations", "ipAddress"),
105+
requestedIP,
106+
"is not a valid IP address",
107+
),
108+
)
109+
}
110+
}
91111
if len(allErrs) == 0 {
92112
return nil, nil
93113
}

internal/webhooks/v1alpha1/ipaddress_webhook_test.go

Lines changed: 118 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,31 @@ func TestIPAddressCreateValidation(t *testing.T) {
5858
claim: corev1.ObjectReference{
5959
Name: "abc",
6060
},
61-
address: "abcd",
61+
address: "192.168.1.10",
62+
},
63+
{
64+
name: "should fail with invalid IP address",
65+
expectErr: true,
66+
addressName: "abc-3",
67+
ipPool: corev1.ObjectReference{
68+
Name: "abc",
69+
},
70+
claim: corev1.ObjectReference{
71+
Name: "abc",
72+
},
73+
address: "not-an-ip-address",
74+
},
75+
{
76+
name: "should fail with malformed IP address format",
77+
expectErr: true,
78+
addressName: "abc-4",
79+
ipPool: corev1.ObjectReference{
80+
Name: "abc",
81+
},
82+
claim: corev1.ObjectReference{
83+
Name: "abc",
84+
},
85+
address: "256.256.256.256",
6286
},
6387
{
6488
name: "should fail without address",
@@ -81,7 +105,7 @@ func TestIPAddressCreateValidation(t *testing.T) {
81105
claim: corev1.ObjectReference{
82106
Name: "abc",
83107
},
84-
address: "abcd",
108+
address: "192.168.1.10",
85109
},
86110
{
87111
name: "should fail without claim name",
@@ -93,7 +117,7 @@ func TestIPAddressCreateValidation(t *testing.T) {
93117
claim: corev1.ObjectReference{
94118
Namespace: "abc",
95119
},
96-
address: "abcd",
120+
address: "192.168.1.10",
97121
},
98122
}
99123

@@ -127,6 +151,80 @@ func TestIPAddressCreateValidation(t *testing.T) {
127151
}
128152
}
129153

154+
func TestIPAddressAnnotationValidation(t *testing.T) {
155+
tests := []struct {
156+
name string
157+
expectErr bool
158+
annotations map[string]string
159+
}{
160+
{
161+
name: "should succeed with valid IP in annotation",
162+
expectErr: false,
163+
annotations: map[string]string{
164+
"ipAddress": "192.168.1.100",
165+
},
166+
},
167+
{
168+
name: "should succeed with valid IPv6 in annotation",
169+
expectErr: false,
170+
annotations: map[string]string{
171+
"ipAddress": "2001:db8::1",
172+
},
173+
},
174+
{
175+
name: "should fail with malformed IP in annotation",
176+
expectErr: true,
177+
annotations: map[string]string{
178+
"ipAddress": "not-an-ip",
179+
},
180+
},
181+
{
182+
name: "should fail with invalid IP format in annotation",
183+
expectErr: true,
184+
annotations: map[string]string{
185+
"ipAddress": "256.256.256.256",
186+
},
187+
},
188+
{
189+
name: "should succeed without IP annotation",
190+
expectErr: false,
191+
annotations: map[string]string{},
192+
},
193+
}
194+
195+
for _, tt := range tests {
196+
t.Run(tt.name, func(t *testing.T) {
197+
g := NewWithT(t)
198+
webhook := &IPAddress{}
199+
200+
obj := &ipamv1.IPAddress{
201+
ObjectMeta: metav1.ObjectMeta{
202+
Namespace: "foo",
203+
Name: "test-address",
204+
Annotations: tt.annotations,
205+
},
206+
Spec: ipamv1.IPAddressSpec{
207+
Pool: corev1.ObjectReference{
208+
Name: "test-pool",
209+
},
210+
Claim: corev1.ObjectReference{
211+
Name: "test-claim",
212+
},
213+
Address: "192.168.1.10",
214+
},
215+
}
216+
217+
if tt.expectErr {
218+
_, err := webhook.ValidateCreate(ctx, obj)
219+
g.Expect(err).To(HaveOccurred())
220+
} else {
221+
_, err := webhook.ValidateCreate(ctx, obj)
222+
g.Expect(err).NotTo(HaveOccurred())
223+
}
224+
})
225+
}
226+
}
227+
130228
func TestIPAddressUpdateValidation(t *testing.T) {
131229
tests := []struct {
132230
name string
@@ -144,7 +242,7 @@ func TestIPAddressUpdateValidation(t *testing.T) {
144242
Claim: corev1.ObjectReference{
145243
Name: "abc",
146244
},
147-
Address: "abcd",
245+
Address: "192.168.1.10",
148246
},
149247
old: &ipamv1.IPAddressSpec{
150248
Pool: corev1.ObjectReference{
@@ -153,7 +251,7 @@ func TestIPAddressUpdateValidation(t *testing.T) {
153251
Claim: corev1.ObjectReference{
154252
Name: "abc",
155253
},
156-
Address: "abcd",
254+
Address: "192.168.1.10",
157255
},
158256
},
159257
{
@@ -163,7 +261,7 @@ func TestIPAddressUpdateValidation(t *testing.T) {
163261
Pool: corev1.ObjectReference{
164262
Name: "abc",
165263
},
166-
Address: "abcd",
264+
Address: "192.168.1.10",
167265
},
168266
old: nil,
169267
},
@@ -174,13 +272,13 @@ func TestIPAddressUpdateValidation(t *testing.T) {
174272
Pool: corev1.ObjectReference{
175273
Name: "abc",
176274
},
177-
Address: "abcd",
275+
Address: "192.168.1.10",
178276
},
179277
old: &ipamv1.IPAddressSpec{
180278
Pool: corev1.ObjectReference{
181279
Name: "abc",
182280
},
183-
Address: "abcde",
281+
Address: "192.168.1.11",
184282
},
185283
},
186284
{
@@ -190,13 +288,13 @@ func TestIPAddressUpdateValidation(t *testing.T) {
190288
Pool: corev1.ObjectReference{
191289
Name: "abc",
192290
},
193-
Address: "abcd",
291+
Address: "192.168.1.10",
194292
},
195293
old: &ipamv1.IPAddressSpec{
196294
Pool: corev1.ObjectReference{
197295
Name: "abcd",
198296
},
199-
Address: "abcd",
297+
Address: "192.168.1.10",
200298
},
201299
},
202300
{
@@ -207,14 +305,14 @@ func TestIPAddressUpdateValidation(t *testing.T) {
207305
Name: "abc",
208306
Namespace: "abc",
209307
},
210-
Address: "abcd",
308+
Address: "192.168.1.10",
211309
},
212310
old: &ipamv1.IPAddressSpec{
213311
Pool: corev1.ObjectReference{
214312
Name: "abc",
215313
Namespace: "abcd",
216314
},
217-
Address: "abcd",
315+
Address: "192.168.1.10",
218316
},
219317
},
220318
{
@@ -225,14 +323,14 @@ func TestIPAddressUpdateValidation(t *testing.T) {
225323
Name: "abc",
226324
Kind: "abc",
227325
},
228-
Address: "abcd",
326+
Address: "192.168.1.10",
229327
},
230328
old: &ipamv1.IPAddressSpec{
231329
Pool: corev1.ObjectReference{
232330
Name: "abc",
233331
Kind: "abcd",
234332
},
235-
Address: "abcd",
333+
Address: "192.168.1.10",
236334
},
237335
},
238336
{
@@ -242,13 +340,13 @@ func TestIPAddressUpdateValidation(t *testing.T) {
242340
Claim: corev1.ObjectReference{
243341
Name: "abc",
244342
},
245-
Address: "abcd",
343+
Address: "192.168.1.10",
246344
},
247345
old: &ipamv1.IPAddressSpec{
248346
Claim: corev1.ObjectReference{
249347
Name: "abcd",
250348
},
251-
Address: "abcd",
349+
Address: "192.168.1.10",
252350
},
253351
},
254352
{
@@ -259,14 +357,14 @@ func TestIPAddressUpdateValidation(t *testing.T) {
259357
Name: "abc",
260358
Namespace: "abc",
261359
},
262-
Address: "abcd",
360+
Address: "192.168.1.10",
263361
},
264362
old: &ipamv1.IPAddressSpec{
265363
Claim: corev1.ObjectReference{
266364
Name: "abc",
267365
Namespace: "abcd",
268366
},
269-
Address: "abcd",
367+
Address: "192.168.1.10",
270368
},
271369
},
272370
{
@@ -277,14 +375,14 @@ func TestIPAddressUpdateValidation(t *testing.T) {
277375
Name: "abc",
278376
Kind: "abc",
279377
},
280-
Address: "abcd",
378+
Address: "192.168.1.10",
281379
},
282380
old: &ipamv1.IPAddressSpec{
283381
Claim: corev1.ObjectReference{
284382
Name: "abc",
285383
Kind: "abcd",
286384
},
287-
Address: "abcd",
385+
Address: "192.168.1.10",
288386
},
289387
},
290388
}

internal/webhooks/v1alpha1/ipclaim_webhook.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,19 @@ func (webhook *IPClaim) ValidateCreate(_ context.Context, obj runtime.Object) (a
6868
)
6969
}
7070

71+
// Validate requested IP address if present in annotations
72+
if requestedIP, ok := c.ObjectMeta.Annotations["ipAddress"]; ok && requestedIP != "" {
73+
if err := validateIP(ipamv1.IPAddressStr(requestedIP)); err != nil {
74+
allErrs = append(allErrs,
75+
field.Invalid(
76+
field.NewPath("metadata", "annotations", "ipAddress"),
77+
requestedIP,
78+
"is not a valid IP address",
79+
),
80+
)
81+
}
82+
}
83+
7184
if len(allErrs) == 0 {
7285
return nil, nil
7386
}
@@ -113,6 +126,19 @@ func (webhook *IPClaim) ValidateUpdate(_ context.Context, oldObj, newObj runtime
113126
)
114127
}
115128

129+
// Validate requested IP address if present in annotations
130+
if requestedIP, ok := newIPClaim.ObjectMeta.Annotations["ipAddress"]; ok && requestedIP != "" {
131+
if validateIP(ipamv1.IPAddressStr(requestedIP)) != nil {
132+
allErrs = append(allErrs,
133+
field.Invalid(
134+
field.NewPath("metadata", "annotations", "ipAddress"),
135+
requestedIP,
136+
"is not a valid IP address",
137+
),
138+
)
139+
}
140+
}
141+
116142
if len(allErrs) == 0 {
117143
return nil, nil
118144
}

0 commit comments

Comments
 (0)