Skip to content

Commit 646cb79

Browse files
committed
network regex validation for powervscluster
1 parent 3bf33db commit 646cb79

File tree

3 files changed

+131
-0
lines changed

3 files changed

+131
-0
lines changed

api/v1beta2/common.go

+9
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ limitations under the License.
1717
package v1beta2
1818

1919
import (
20+
"regexp"
2021
"strconv"
2122

2223
"k8s.io/apimachinery/pkg/util/intstr"
@@ -42,16 +43,24 @@ func validateIBMPowerVSResourceReference(res IBMPowerVSResourceReference, resTyp
4243
if res.ID != nil && res.Name != nil {
4344
return false, field.Invalid(field.NewPath("spec", resType), res, "Only one of "+resType+" - ID or Name may be specified")
4445
}
46+
4547
return true, nil
4648
}
4749

4850
func validateIBMPowerVSNetworkReference(res IBMPowerVSResourceReference) (bool, *field.Error) {
51+
// Ensure only one of ID, Name, or RegEx is specified
4952
if (res.ID != nil && res.Name != nil) || (res.ID != nil && res.RegEx != nil) || (res.Name != nil && res.RegEx != nil) {
5053
return false, field.Invalid(field.NewPath("spec", "Network"), res, "Only one of Network - ID, Name or RegEx can be specified")
5154
}
5255
return true, nil
5356
}
5457

58+
// regexMatches validates if a given regex matches the target string.
59+
func regexMatches(pattern, target string) bool {
60+
matched, err := regexp.MatchString(pattern, target)
61+
return err == nil && matched
62+
}
63+
5564
func validateIBMPowerVSMemoryValues(resValue int32) bool {
5665
if val := float64(resValue); val < 2 {
5766
return false

api/v1beta2/ibmpowervscluster_webhook.go

+34
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,44 @@ func (r *IBMPowerVSCluster) validateIBMPowerVSCluster() (admission.Warnings, err
9595
r.Name, allErrs)
9696
}
9797

98+
func (r *IBMPowerVSCluster) validateNetworkRegex() (bool, *field.Error) {
99+
if r.Spec.Network.RegEx != nil {
100+
var targetName string
101+
var validationMessage string
102+
103+
if *r.Spec.DHCPServer.Name != "" {
104+
targetName = *r.Spec.DHCPServer.Name
105+
validationMessage = "The RegEx should match the DHCP server name when the DHCP server is set"
106+
} else {
107+
if r.GetObjectMeta().GetName() == "" {
108+
return false, field.Required(
109+
field.NewPath("metadata", "name"),
110+
"Cluster name must be set when Network.RegEx is provided and DHCP server name is not set",
111+
)
112+
}
113+
targetName = r.GetObjectMeta().GetName()
114+
validationMessage = "The RegEx should match the cluster name when the DHCP server is not set"
115+
}
116+
117+
if !regexMatches(*r.Spec.Network.RegEx, targetName) {
118+
return false, field.Invalid(
119+
field.NewPath("spec", "Network", "RegEx"),
120+
r.Spec.Network.RegEx,
121+
validationMessage,
122+
)
123+
}
124+
}
125+
126+
return true, nil
127+
}
128+
98129
func (r *IBMPowerVSCluster) validateIBMPowerVSClusterNetwork() *field.Error {
99130
if res, err := validateIBMPowerVSNetworkReference(r.Spec.Network); !res {
100131
return err
101132
}
133+
if res, err := r.validateNetworkRegex(); !res {
134+
return err
135+
}
102136
return nil
103137
}
104138

api/v1beta2/ibmpowervscluster_webhook_test.go

+88
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,36 @@ func TestIBMPowerVSCluster_create(t *testing.T) {
6868
},
6969
wantErr: true,
7070
},
71+
{
72+
name: "Should error network regex and dhcp server name is set but does not match dhcp server name",
73+
powervsCluster: &IBMPowerVSCluster{
74+
Spec: IBMPowerVSClusterSpec{
75+
ServiceInstanceID: "capi-si-id",
76+
Network: IBMPowerVSResourceReference{
77+
RegEx: ptr.To("^capi$"),
78+
},
79+
DHCPServer: &DHCPServer{
80+
Name: ptr.To("test"),
81+
},
82+
},
83+
},
84+
wantErr: true,
85+
},
86+
{
87+
name: "Should error if only network regex is set, dhcp server name is not set and does not match cluster name",
88+
powervsCluster: &IBMPowerVSCluster{
89+
Spec: IBMPowerVSClusterSpec{
90+
ServiceInstanceID: "capi-si-id",
91+
Network: IBMPowerVSResourceReference{
92+
RegEx: ptr.To("^capi$"),
93+
},
94+
},
95+
ObjectMeta: metav1.ObjectMeta{
96+
Name: "test",
97+
},
98+
},
99+
wantErr: true,
100+
},
71101
}
72102

73103
for _, tc := range tests {
@@ -141,6 +171,9 @@ func TestIBMPowerVSCluster_update(t *testing.T) {
141171
Network: IBMPowerVSResourceReference{
142172
RegEx: ptr.To("^capi-net-id$"),
143173
},
174+
DHCPServer: &DHCPServer{
175+
Name: ptr.To("capi-net-id"),
176+
},
144177
},
145178
},
146179
newPowervsCluster: &IBMPowerVSCluster{
@@ -149,6 +182,9 @@ func TestIBMPowerVSCluster_update(t *testing.T) {
149182
Network: IBMPowerVSResourceReference{
150183
RegEx: ptr.To("^capi-net-id$"),
151184
},
185+
DHCPServer: &DHCPServer{
186+
Name: ptr.To("capi-net-id"),
187+
},
152188
},
153189
},
154190
wantErr: false,
@@ -175,6 +211,58 @@ func TestIBMPowerVSCluster_update(t *testing.T) {
175211
},
176212
wantErr: true,
177213
},
214+
{
215+
name: "Should error if network regex and dhcp server name is set but network regex does not match dhcp server name",
216+
oldPowervsCluster: &IBMPowerVSCluster{
217+
Spec: IBMPowerVSClusterSpec{
218+
ServiceInstanceID: "capi-si-id",
219+
Network: IBMPowerVSResourceReference{
220+
RegEx: ptr.To("^capi$"),
221+
},
222+
DHCPServer: &DHCPServer{
223+
Name: ptr.To("capi"),
224+
},
225+
},
226+
},
227+
newPowervsCluster: &IBMPowerVSCluster{
228+
Spec: IBMPowerVSClusterSpec{
229+
ServiceInstanceID: "capi-si-id",
230+
Network: IBMPowerVSResourceReference{
231+
RegEx: ptr.To("^capi$"),
232+
},
233+
DHCPServer: &DHCPServer{
234+
Name: ptr.To("test"),
235+
},
236+
},
237+
},
238+
wantErr: true,
239+
},
240+
{
241+
name: "Should error if network regex is set, dhcp server name is not set and network regex does not match cluster name",
242+
oldPowervsCluster: &IBMPowerVSCluster{
243+
Spec: IBMPowerVSClusterSpec{
244+
ServiceInstanceID: "capi-si-id",
245+
Network: IBMPowerVSResourceReference{
246+
RegEx: ptr.To("^capi$"),
247+
},
248+
DHCPServer: &DHCPServer{
249+
Name: ptr.To("capi"),
250+
},
251+
},
252+
},
253+
newPowervsCluster: &IBMPowerVSCluster{
254+
Spec: IBMPowerVSClusterSpec{
255+
ServiceInstanceID: "capi-si-id",
256+
Network: IBMPowerVSResourceReference{
257+
RegEx: ptr.To("^capi$"),
258+
},
259+
},
260+
ObjectMeta: metav1.ObjectMeta{
261+
Name: "capi",
262+
},
263+
},
264+
wantErr: true,
265+
},
178266
}
179267

180268
for _, tc := range tests {

0 commit comments

Comments
 (0)