Skip to content

Commit 3049563

Browse files
committed
Nutanix: support multi-subnets in Machine providerSpec
1 parent 227a541 commit 3049563

File tree

2 files changed

+96
-21
lines changed

2 files changed

+96
-21
lines changed

pkg/webhooks/machine_webhook.go

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"encoding/json"
66
"errors"
77
"fmt"
8+
"reflect"
89
"regexp"
910
goruntime "runtime"
1011
"strconv"
@@ -1588,19 +1589,30 @@ func validateNutanix(m *machinev1beta1.Machine, config *admissionConfig) (bool,
15881589
if err := validateNutanixResourceIdentifier("image", providerSpec.Image); err != nil {
15891590
errs = append(errs, err)
15901591
}
1591-
// Currently, we only support one subnet per VM in Openshift
1592-
// We may extend this to support more than one subnet per VM in future releases
1593-
if len(providerSpec.Subnets) == 0 {
1592+
1593+
numSubnets := len(providerSpec.Subnets)
1594+
switch {
1595+
case numSubnets == 0:
15941596
subnets, _ := json.Marshal(providerSpec.Subnets)
15951597
errs = append(errs, field.Invalid(field.NewPath("providerSpec", "subnets"), string(subnets), "missing subnets: nodes may fail to start if no subnets are configured"))
1596-
} else if len(providerSpec.Subnets) > 1 {
1597-
subnets, _ := json.Marshal(providerSpec.Subnets)
1598-
errs = append(errs, field.Invalid(field.NewPath("providerSpec", "subnets"), string(subnets), "too many subnets: currently nutanix platform supports one subnet per VM but more than one subnets are configured"))
1599-
}
1598+
case numSubnets > 32:
1599+
errs = append(errs, field.TooMany(field.NewPath("providerSpec", "subnets"), numSubnets, 32))
1600+
default:
1601+
subnets := []machinev1.NutanixResourceIdentifier{}
1602+
for _, subnet := range providerSpec.Subnets {
1603+
if err := validateNutanixResourceIdentifier("subnet", subnet); err != nil {
1604+
errs = append(errs, err)
1605+
} else {
1606+
// check duplication
1607+
for _, other := range subnets {
1608+
if reflect.DeepEqual(subnet, other) {
1609+
subnetData, _ := json.Marshal(subnet)
1610+
errs = append(errs, field.Invalid(field.NewPath("providerSpec", "subnets"), string(subnetData), "should not configure duplicate subnet value"))
1611+
}
1612+
}
1613+
}
16001614

1601-
for _, subnet := range providerSpec.Subnets {
1602-
if err := validateNutanixResourceIdentifier("subnet", subnet); err != nil {
1603-
errs = append(errs, err)
1615+
subnets = append(subnets, subnet)
16041616
}
16051617
}
16061618

pkg/webhooks/machine_webhook_test.go

Lines changed: 74 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1146,6 +1146,79 @@ func TestMachineCreation(t *testing.T) {
11461146
},
11471147
expectedError: "[providerSpec.cluster.type: Invalid value: \"\": cluster type must be one of name or uuid, providerSpec.image.type: Invalid value: \"\": image type must be one of name or uuid, providerSpec.subnets: Invalid value: \"null\": missing subnets: nodes may fail to start if no subnets are configured]",
11481148
},
1149+
{
1150+
name: "with nutanix and too many subnets set",
1151+
platformType: osconfigv1.NutanixPlatformType,
1152+
clusterID: "nutanix-cluster",
1153+
presetClusterID: true,
1154+
providerSpecValue: &kruntime.RawExtension{
1155+
Object: &machinev1.NutanixMachineProviderConfig{
1156+
VCPUSockets: minNutanixCPUSockets,
1157+
VCPUsPerSocket: minNutanixCPUPerSocket,
1158+
MemorySize: resource.MustParse(fmt.Sprintf("%dMi", minNutanixMemoryMiB)),
1159+
SystemDiskSize: resource.MustParse(fmt.Sprintf("%dGi", minNutanixDiskGiB)),
1160+
Subnets: []machinev1.NutanixResourceIdentifier{
1161+
{Type: machinev1.NutanixIdentifierName, Name: ptr.To[string]("subnet-1")},
1162+
{Type: machinev1.NutanixIdentifierName, Name: ptr.To[string]("subnet-2")},
1163+
{Type: machinev1.NutanixIdentifierName, Name: ptr.To[string]("subnet-3")},
1164+
{Type: machinev1.NutanixIdentifierName, Name: ptr.To[string]("subnet-4")},
1165+
{Type: machinev1.NutanixIdentifierName, Name: ptr.To[string]("subnet-5")},
1166+
{Type: machinev1.NutanixIdentifierName, Name: ptr.To[string]("subnet-6")},
1167+
{Type: machinev1.NutanixIdentifierName, Name: ptr.To[string]("subnet-7")},
1168+
{Type: machinev1.NutanixIdentifierName, Name: ptr.To[string]("subnet-8")},
1169+
{Type: machinev1.NutanixIdentifierName, Name: ptr.To[string]("subnet-9")},
1170+
{Type: machinev1.NutanixIdentifierName, Name: ptr.To[string]("subnet-10")},
1171+
{Type: machinev1.NutanixIdentifierName, Name: ptr.To[string]("subnet-11")},
1172+
{Type: machinev1.NutanixIdentifierName, Name: ptr.To[string]("subnet-12")},
1173+
{Type: machinev1.NutanixIdentifierName, Name: ptr.To[string]("subnet-13")},
1174+
{Type: machinev1.NutanixIdentifierName, Name: ptr.To[string]("subnet-14")},
1175+
{Type: machinev1.NutanixIdentifierName, Name: ptr.To[string]("subnet-15")},
1176+
{Type: machinev1.NutanixIdentifierName, Name: ptr.To[string]("subnet-16")},
1177+
{Type: machinev1.NutanixIdentifierName, Name: ptr.To[string]("subnet-17")},
1178+
{Type: machinev1.NutanixIdentifierName, Name: ptr.To[string]("subnet-18")},
1179+
{Type: machinev1.NutanixIdentifierName, Name: ptr.To[string]("subnet-19")},
1180+
{Type: machinev1.NutanixIdentifierName, Name: ptr.To[string]("subnet-20")},
1181+
{Type: machinev1.NutanixIdentifierName, Name: ptr.To[string]("subnet-21")},
1182+
{Type: machinev1.NutanixIdentifierName, Name: ptr.To[string]("subnet-22")},
1183+
{Type: machinev1.NutanixIdentifierName, Name: ptr.To[string]("subnet-23")},
1184+
{Type: machinev1.NutanixIdentifierName, Name: ptr.To[string]("subnet-24")},
1185+
{Type: machinev1.NutanixIdentifierName, Name: ptr.To[string]("subnet-25")},
1186+
{Type: machinev1.NutanixIdentifierName, Name: ptr.To[string]("subnet-26")},
1187+
{Type: machinev1.NutanixIdentifierName, Name: ptr.To[string]("subnet-27")},
1188+
{Type: machinev1.NutanixIdentifierName, Name: ptr.To[string]("subnet-28")},
1189+
{Type: machinev1.NutanixIdentifierName, Name: ptr.To[string]("subnet-29")},
1190+
{Type: machinev1.NutanixIdentifierName, Name: ptr.To[string]("subnet-30")},
1191+
{Type: machinev1.NutanixIdentifierName, Name: ptr.To[string]("subnet-31")},
1192+
{Type: machinev1.NutanixIdentifierName, Name: ptr.To[string]("subnet-32")},
1193+
{Type: machinev1.NutanixIdentifierName, Name: ptr.To[string]("subnet-33")},
1194+
},
1195+
Cluster: machinev1.NutanixResourceIdentifier{Type: machinev1.NutanixIdentifierName, Name: ptr.To[string]("cluster-1")},
1196+
Image: machinev1.NutanixResourceIdentifier{Type: machinev1.NutanixIdentifierName, Name: ptr.To[string]("image-1")},
1197+
},
1198+
},
1199+
expectedError: "providerSpec.subnets: Too many: 33: must have at most 32 items",
1200+
},
1201+
{
1202+
name: "with nutanix and duplicate subnet set",
1203+
platformType: osconfigv1.NutanixPlatformType,
1204+
clusterID: "nutanix-cluster",
1205+
presetClusterID: true,
1206+
providerSpecValue: &kruntime.RawExtension{
1207+
Object: &machinev1.NutanixMachineProviderConfig{
1208+
VCPUSockets: minNutanixCPUSockets,
1209+
VCPUsPerSocket: minNutanixCPUPerSocket,
1210+
MemorySize: resource.MustParse(fmt.Sprintf("%dMi", minNutanixMemoryMiB)),
1211+
SystemDiskSize: resource.MustParse(fmt.Sprintf("%dGi", minNutanixDiskGiB)),
1212+
Subnets: []machinev1.NutanixResourceIdentifier{
1213+
{Type: machinev1.NutanixIdentifierName, Name: ptr.To[string]("subnet-1")},
1214+
{Type: machinev1.NutanixIdentifierName, Name: ptr.To[string]("subnet-1")},
1215+
},
1216+
Cluster: machinev1.NutanixResourceIdentifier{Type: machinev1.NutanixIdentifierName, Name: ptr.To[string]("cluster-1")},
1217+
Image: machinev1.NutanixResourceIdentifier{Type: machinev1.NutanixIdentifierName, Name: ptr.To[string]("image-1")},
1218+
},
1219+
},
1220+
expectedError: `providerSpec.subnets: Invalid value: "{\"type\":\"name\",\"name\":\"subnet-1\"}": should not configure duplicate subnet value`,
1221+
},
11491222
{
11501223
name: "with nutanix and the required fields set",
11511224
platformType: osconfigv1.NutanixPlatformType,
@@ -1159,6 +1232,7 @@ func TestMachineCreation(t *testing.T) {
11591232
SystemDiskSize: resource.MustParse(fmt.Sprintf("%dGi", minNutanixDiskGiB)),
11601233
Subnets: []machinev1.NutanixResourceIdentifier{
11611234
{Type: machinev1.NutanixIdentifierName, Name: ptr.To[string]("subnet-1")},
1235+
{Type: machinev1.NutanixIdentifierName, Name: ptr.To[string]("subnet-2")},
11621236
},
11631237
Cluster: machinev1.NutanixResourceIdentifier{Type: machinev1.NutanixIdentifierName, Name: ptr.To[string]("cluster-1")},
11641238
Image: machinev1.NutanixResourceIdentifier{Type: machinev1.NutanixIdentifierName, Name: ptr.To[string]("image-1")},
@@ -5056,17 +5130,6 @@ func TestValidateNutanixProviderSpec(t *testing.T) {
50565130
expectedError: "providerSpec.subnets: Invalid value: \"[]\": missing subnets: nodes may fail to start if no subnets are configured",
50575131
//expectedWarnings: []string{"providerSpec.subnets: missing subnets: nodes may fail to start if no subnets are configured"},
50585132
},
5059-
{
5060-
testCase: "with too many subnets provided",
5061-
modifySpec: func(p *machinev1.NutanixMachineProviderConfig) {
5062-
p.Subnets = []machinev1.NutanixResourceIdentifier{
5063-
{Type: machinev1.NutanixIdentifierName, Name: ptr.To[string]("subnet-1")},
5064-
{Type: machinev1.NutanixIdentifierName, Name: ptr.To[string]("subnet-2")},
5065-
}
5066-
},
5067-
expectedOk: false,
5068-
expectedError: "providerSpec.subnets: Invalid value: \"[{\\\"type\\\":\\\"name\\\",\\\"name\\\":\\\"subnet-1\\\"},{\\\"type\\\":\\\"name\\\",\\\"name\\\":\\\"subnet-2\\\"}]\": too many subnets: currently nutanix platform supports one subnet per VM but more than one subnets are configured",
5069-
},
50705133
{
50715134
testCase: "with no userDataSecret provided",
50725135
modifySpec: func(p *machinev1.NutanixMachineProviderConfig) {

0 commit comments

Comments
 (0)