Skip to content

Commit 267d61a

Browse files
committed
Remove webhook validation for networks
We now support custom network names. `ctlplane` network name or the network for which serviceNet is `ctlplane` could be anywhere in the order and it won't matter. Signed-off-by: rabi <ramishra@redhat.com>
1 parent 7456407 commit 267d61a

6 files changed

Lines changed: 128 additions & 70 deletions

File tree

apis/dataplane/v1beta1/openstackdataplanenodeset_types.go

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ package v1beta1
1919
import (
2020
"context"
2121
"fmt"
22-
"strings"
2322

2423
"golang.org/x/exp/slices"
2524
"sigs.k8s.io/controller-runtime/pkg/client"
@@ -349,29 +348,3 @@ func (r *OpenStackDataPlaneNodeSetSpec) TLSMatch(controlPlane openstackv1.OpenSt
349348
}
350349
return nil
351350
}
352-
353-
// Validate NodeSet networks
354-
func (r *OpenStackDataPlaneNodeSetSpec) ValidateNetworks() (errors field.ErrorList) {
355-
for nodeName, node := range r.Nodes {
356-
if len(node.Networks) > 0 && !strings.EqualFold(string(node.Networks[0].Name), CtlPlaneNetwork) {
357-
errors = append(errors, field.Invalid(
358-
field.NewPath("spec").Child("nodes").Child(nodeName).Child("networks"),
359-
node.Networks,
360-
fmt.Sprintf(
361-
"node %s error: networks should start with %s got %s instead",
362-
node.HostName, CtlPlaneNetwork, node.Networks[0].Name,
363-
)))
364-
}
365-
}
366-
if len(r.NodeTemplate.Networks) > 0 && !strings.EqualFold(string(r.NodeTemplate.Networks[0].Name), CtlPlaneNetwork) {
367-
errors = append(errors, field.Invalid(
368-
field.NewPath("spec").Child("nodeTemplate").Child("networks"),
369-
r.NodeTemplate.Networks,
370-
fmt.Sprintf(
371-
"networks should start with %s got %s instead",
372-
CtlPlaneNetwork, r.NodeTemplate.Networks[0].Name,
373-
)))
374-
}
375-
376-
return errors
377-
}

apis/dataplane/v1beta1/openstackdataplanenodeset_webhook.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,6 @@ func (r *OpenStackDataPlaneNodeSet) ValidateCreate() (admission.Warnings, error)
114114
if err != nil {
115115
return nil, err
116116
}
117-
errors = append(errors, r.Spec.ValidateNetworks()...)
118-
119117
// Check if OpenStackDataPlaneNodeSet name matches RFC1123 for use in labels
120118
validate := validator.New()
121119
if err := validate.Var(r.Name, "hostname_rfc1123"); err != nil {
@@ -185,7 +183,6 @@ func (r *OpenStackDataPlaneNodeSet) ValidateUpdate(old runtime.Object) (admissio
185183
return nil, err
186184
}
187185

188-
errors = append(errors, r.Spec.ValidateNetworks()...)
189186
errors = append(errors, r.Spec.ValidateUpdate(&oldNodeSet.Spec)...)
190187

191188
if errors != nil {

pkg/dataplane/ipam.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,13 +355,24 @@ func reserveIPs(ctx context.Context, helper *helper.Helper,
355355

356356
// CreateOrPatch IPSets
357357
for nodeName, node := range instance.Spec.Nodes {
358+
foundCtlPlane := false
358359
nets := node.Networks
359360
hostName := node.HostName
360361
if len(nets) == 0 {
361362
nets = instance.Spec.NodeTemplate.Networks
362363
}
363364

364365
if len(nets) > 0 {
366+
for _, net := range nets {
367+
if strings.EqualFold(string(net.Name), dataplanev1.CtlPlaneNetwork) ||
368+
netServiceNetMap[strings.ToLower(string(net.Name))] == dataplanev1.CtlPlaneNetwork {
369+
foundCtlPlane = true
370+
}
371+
}
372+
if !foundCtlPlane {
373+
msg := fmt.Sprintf("ctlplane network should be defined for node %s", nodeName)
374+
return nil, netServiceNetMap, fmt.Errorf(msg)
375+
}
365376
ipSet := &infranetworkv1.IPSet{
366377
ObjectMeta: metav1.ObjectMeta{
367378
Namespace: instance.Namespace,

tests/functional/dataplane/base_test.go

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ func DefaultDataPlaneNodeSetSpec(nodeSetName string) map[string]interface{} {
165165
fmt.Sprintf("%s-node-1", nodeSetName): map[string]interface{}{
166166
"hostName": "edpm-compute-node-1",
167167
"networks": []infrav1.IPSetNetwork{
168+
{Name: "networkinternal", SubnetName: "subnet1"},
168169
{Name: "ctlplane", SubnetName: "subnet1"},
169170
},
170171
},
@@ -197,6 +198,7 @@ func DuplicateServiceNodeSetSpec(nodeSetName string) map[string]interface{} {
197198
fmt.Sprintf("%s-node-1", nodeSetName): map[string]interface{}{
198199
"hostName": "edpm-compute-node-1",
199200
"networks": []infrav1.IPSetNetwork{
201+
{Name: "networkinternal", SubnetName: "subnet1"},
200202
{Name: "ctlplane", SubnetName: "subnet1"},
201203
},
202204
},
@@ -213,6 +215,7 @@ func DefaultDataPlaneNoNodeSetSpec(tlsEnabled bool) map[string]interface{} {
213215
"preProvisioned": true,
214216
"nodeTemplate": map[string]interface{}{
215217
"networks": []infrav1.IPSetNetwork{
218+
{Name: "networkinternal", SubnetName: "subnet1"},
216219
{Name: "ctlplane", SubnetName: "subnet1"},
217220
},
218221
"ansibleSSHPrivateKeySecret": "dataplane-ansible-ssh-private-key-secret",
@@ -290,9 +293,10 @@ func SingleGlobalServiceDeploymentSpec() map[string]interface{} {
290293
func DefaultNetConfigSpec() map[string]interface{} {
291294
return map[string]interface{}{
292295
"networks": []map[string]interface{}{{
293-
"dnsDomain": "test-domain.test",
294-
"mtu": 1500,
295-
"name": "CtlPLane",
296+
"dnsDomain": "test-domain.test",
297+
"mtu": 1500,
298+
"name": "CtlPlane",
299+
"serviceNet": "ctlplane",
296300
"subnets": []map[string]interface{}{{
297301
"allocationRanges": []map[string]interface{}{{
298302
"end": "172.20.12.120",
@@ -304,6 +308,22 @@ func DefaultNetConfigSpec() map[string]interface{} {
304308
"gateway": "172.20.12.1",
305309
},
306310
},
311+
}, {
312+
"dnsDomain": "test-domain.test",
313+
"mtu": 1500,
314+
"name": "networkinternal",
315+
"serviceNet": "internalapi",
316+
"subnets": []map[string]interface{}{{
317+
"allocationRanges": []map[string]interface{}{{
318+
"end": "172.20.13.120",
319+
"start": "172.20.13.0",
320+
},
321+
},
322+
"name": "subnet1",
323+
"cidr": "172.20.13.0/16",
324+
"gateway": "172.20.13.1",
325+
},
326+
},
307327
},
308328
},
309329
}
@@ -358,6 +378,15 @@ func SimulateIPSetComplete(name types.NamespacedName) {
358378
Gateway: &gateway,
359379
ServiceNetwork: "ctlplane",
360380
},
381+
{
382+
Address: "172.20.13.76",
383+
Cidr: "172.20.13.0/16",
384+
MTU: 1500,
385+
Network: "NetworkInternal",
386+
Subnet: "subnet1",
387+
Gateway: &gateway,
388+
ServiceNetwork: "internalapi",
389+
},
361390
}
362391
// This can return conflict so we have the gomega.Eventually block to retry
363392
g.Expect(th.K8sClient.Status().Update(th.Ctx, IPSet)).To(Succeed())

tests/functional/dataplane/openstackdataplanenodeset_controller_test.go

Lines changed: 85 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,46 @@ var _ = Describe("Dataplane NodeSet Test", func() {
145145
})
146146
})
147147

148+
When("A Dataplane nodeset is created and no ctlplane network in networks", func() {
149+
BeforeEach(func() {
150+
DeferCleanup(th.DeleteInstance,
151+
CreateNetConfig(dataplaneNetConfigName, DefaultNetConfigSpec()))
152+
153+
DeferCleanup(th.DeleteInstance,
154+
CreateDataplaneNodeSet(dataplaneNodeSetName,
155+
DefaultDataPlaneNoNodeSetSpec(false)))
156+
})
157+
158+
It("Should fail to set NodeSetIPReservationReadyCondition true when ctlplane is not in the networks", func() {
159+
Eventually(func(g Gomega) {
160+
instance := GetDataplaneNodeSet(dataplaneNodeSetName)
161+
instance.Spec.NodeTemplate.Networks[1].Name = "notctlplane"
162+
g.Expect(th.K8sClient.Update(th.Ctx, instance)).Should(Succeed())
163+
th.ExpectCondition(
164+
dataplaneNodeSetName,
165+
ConditionGetterFunc(DataplaneConditionGetter),
166+
condition.ReadyCondition,
167+
corev1.ConditionFalse,
168+
)
169+
th.ExpectCondition(
170+
dataplaneNodeSetName,
171+
ConditionGetterFunc(DataplaneConditionGetter),
172+
condition.InputReadyCondition,
173+
corev1.ConditionUnknown,
174+
)
175+
th.ExpectCondition(
176+
dataplaneNodeSetName,
177+
ConditionGetterFunc(DataplaneConditionGetter),
178+
dataplanev1.NodeSetIPReservationReadyCondition,
179+
corev1.ConditionFalse,
180+
)
181+
conditions := DataplaneConditionGetter(dataplaneNodeSetName)
182+
message := &conditions.Get(dataplanev1.NodeSetIPReservationReadyCondition).Message
183+
g.Expect(*message).Should(ContainSubstring("ctlplane network should be defined for node"))
184+
}, timeout, interval).Should(Succeed())
185+
})
186+
})
187+
148188
When("A Dataplane nodeset is created and no dnsmasq", func() {
149189
BeforeEach(func() {
150190
DeferCleanup(th.DeleteInstance,
@@ -292,10 +332,15 @@ var _ = Describe("Dataplane NodeSet Test", func() {
292332
AnsibleVars: nil,
293333
},
294334
ExtraMounts: nil,
295-
Networks: []infrav1.IPSetNetwork{{
296-
Name: "ctlplane",
297-
SubnetName: "subnet1",
298-
},
335+
Networks: []infrav1.IPSetNetwork{
336+
{
337+
Name: "networkinternal",
338+
SubnetName: "subnet1",
339+
},
340+
{
341+
Name: "ctlplane",
342+
SubnetName: "subnet1",
343+
},
299344
},
300345
},
301346
Env: nil,
@@ -418,10 +463,15 @@ var _ = Describe("Dataplane NodeSet Test", func() {
418463
},
419464
NodeTemplate: dataplanev1.NodeTemplate{
420465
AnsibleSSHPrivateKeySecret: "dataplane-ansible-ssh-private-key-secret",
421-
Networks: []infrav1.IPSetNetwork{{
422-
Name: "ctlplane",
423-
SubnetName: "subnet1",
424-
},
466+
Networks: []infrav1.IPSetNetwork{
467+
{
468+
Name: "networkinternal",
469+
SubnetName: "subnet1",
470+
},
471+
{
472+
Name: "ctlplane",
473+
SubnetName: "subnet1",
474+
},
425475
},
426476
ManagementNetwork: "ctlplane",
427477
Ansible: dataplanev1.AnsibleOpts{
@@ -724,10 +774,15 @@ var _ = Describe("Dataplane NodeSet Test", func() {
724774
DeferCleanup(th.DeleteInstance, CreateNetConfig(dataplaneNetConfigName, DefaultNetConfigSpec()))
725775
nodeOverrideSpec := dataplanev1.NodeSection{
726776
HostName: dataplaneNodeName.Name,
727-
Networks: []infrav1.IPSetNetwork{{
728-
Name: "ctlplane",
729-
SubnetName: "subnet1",
730-
},
777+
Networks: []infrav1.IPSetNetwork{
778+
{
779+
Name: "networkinternal",
780+
SubnetName: "subnet1",
781+
},
782+
{
783+
Name: "ctlplane",
784+
SubnetName: "subnet1",
785+
},
731786
},
732787
Ansible: dataplanev1.AnsibleOpts{
733788
AnsibleUser: "test-user",
@@ -860,10 +915,15 @@ var _ = Describe("Dataplane NodeSet Test", func() {
860915
},
861916
NodeTemplate: dataplanev1.NodeTemplate{
862917
AnsibleSSHPrivateKeySecret: "dataplane-ansible-ssh-private-key-secret",
863-
Networks: []infrav1.IPSetNetwork{{
864-
Name: "ctlplane",
865-
SubnetName: "subnet1",
866-
},
918+
Networks: []infrav1.IPSetNetwork{
919+
{
920+
Name: "networkinternal",
921+
SubnetName: "subnet1",
922+
},
923+
{
924+
Name: "ctlplane",
925+
SubnetName: "subnet1",
926+
},
867927
},
868928
ManagementNetwork: "ctlplane",
869929
Ansible: dataplanev1.AnsibleOpts{
@@ -1164,10 +1224,15 @@ var _ = Describe("Dataplane NodeSet Test", func() {
11641224
DeferCleanup(th.DeleteInstance, CreateDNSMasq(dnsMasqName, DefaultDNSMasqSpec()))
11651225
nodeOverrideSpec := dataplanev1.NodeSection{
11661226
HostName: dataplaneNodeName.Name,
1167-
Networks: []infrav1.IPSetNetwork{{
1168-
Name: "ctlplane",
1169-
SubnetName: "subnet1",
1170-
},
1227+
Networks: []infrav1.IPSetNetwork{
1228+
{
1229+
Name: "networkinternal",
1230+
SubnetName: "subnet1",
1231+
},
1232+
{
1233+
Name: "ctlplane",
1234+
SubnetName: "subnet1",
1235+
},
11711236
},
11721237
Ansible: dataplanev1.AnsibleOpts{
11731238
AnsibleUser: "test-user",

tests/functional/dataplane/openstackdataplanenodeset_webhook_test.go

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -243,21 +243,4 @@ var _ = Describe("DataplaneNodeSet Webhook", func() {
243243
dataplaneDeploymentName.Name, string(v1beta1.NodeSetDeploymentReadyCondition))))
244244
})
245245
})
246-
When("networks are out of order", func() {
247-
BeforeEach(func() {
248-
nodeSetSpec := DefaultDataPlaneNoNodeSetSpec(false)
249-
dataplaneNodeSetName.Name = "unordered"
250-
DeferCleanup(th.DeleteInstance, CreateDataplaneNodeSet(dataplaneNodeSetName, nodeSetSpec))
251-
})
252-
253-
It("Should fail when ctlplane is not the first network", func() {
254-
Eventually(func(_ Gomega) string {
255-
dataplaneNodeSetName.Name = "unordered"
256-
instance := GetDataplaneNodeSet(dataplaneNodeSetName)
257-
instance.Spec.NodeTemplate.Networks[0].Name = "wrong"
258-
err := th.K8sClient.Update(th.Ctx, instance)
259-
return fmt.Sprintf("%s", err)
260-
}).Should(ContainSubstring("networks should start with ctlplane got wrong instead"))
261-
})
262-
})
263246
})

0 commit comments

Comments
 (0)