Skip to content

Commit

Permalink
Fix potential VM validation webhook for Spec.Network
Browse files Browse the repository at this point in the history
If the VM Spec.Network was changed to/from nil, the validation webhook
would NPE. I think the stems from late in v1a2 we decided to make most
of the top level Spec/Status fields pointers and this was just missed.

Add a few basic update tests for VM Spec.Network.
  • Loading branch information
Bryan Venteicher committed Dec 13, 2024
1 parent 32a7325 commit a501746
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1230,8 +1230,13 @@ func (v validator) validateImmutableNetwork(ctx *pkgctx.WebhookRequestContext, v

p := field.NewPath("spec", "network")

oldInterfaces := oldVM.Spec.Network.Interfaces
newInterfaces := vm.Spec.Network.Interfaces
var oldInterfaces, newInterfaces []vmopv1.VirtualMachineNetworkInterfaceSpec
if oldNetwork != nil {
oldInterfaces = oldNetwork.Interfaces
}
if newNetwork != nil {
newInterfaces = newNetwork.Interfaces
}

if len(oldInterfaces) != len(newInterfaces) {
return append(allErrs, field.Forbidden(p.Child("interfaces"), "network interfaces cannot be added or removed"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3148,7 +3148,7 @@ func unitTestsValidateUpdate() {
},
),

Entry("alow changing image for privileged users when FSS_WCP_VMSERVICE_INCREMENTAL_RESTORE is enabled, and Registered annotation is present",
Entry("allow changing image for privileged users when FSS_WCP_VMSERVICE_INCREMENTAL_RESTORE is enabled, and Registered annotation is present",
testParams{
setup: func(ctx *unitValidatingWebhookContext) {
pkgcfg.SetContext(ctx, func(config *pkgcfg.Config) {
Expand Down Expand Up @@ -3687,7 +3687,7 @@ func unitTestsValidateUpdate() {
},
),

Entry("alow removing CD-ROM when VM is powered off",
Entry("allow removing CD-ROM when VM is powered off",
testParams{
setup: func(ctx *unitValidatingWebhookContext) {
ctx.vm.Spec.Cdrom = []vmopv1.VirtualMachineCdromSpec{}
Expand Down Expand Up @@ -4014,6 +4014,98 @@ func unitTestsValidateUpdate() {
),
)
})

Context("Network", func() {

DescribeTable("network update", doTest,
Entry("allow Network go from nil to not-nil",
testParams{
setup: func(ctx *unitValidatingWebhookContext) {
ctx.oldVM.Spec.Network = nil
ctx.vm.Spec.Network = &vmopv1.VirtualMachineNetworkSpec{}
},
expectAllowed: true,
},
),
Entry("allow Network go from not-nil to nil",
testParams{
setup: func(ctx *unitValidatingWebhookContext) {
ctx.oldVM.Spec.Network = &vmopv1.VirtualMachineNetworkSpec{}
ctx.vm.Spec.Network = nil
},
expectAllowed: true,
},
),
Entry("disallow adding Network Interface",
testParams{
setup: func(ctx *unitValidatingWebhookContext) {
ctx.oldVM.Spec.Network = &vmopv1.VirtualMachineNetworkSpec{
Interfaces: []vmopv1.VirtualMachineNetworkInterfaceSpec{
{
Name: "eth0",
},
},
}
ctx.vm.Spec.Network = &vmopv1.VirtualMachineNetworkSpec{
Interfaces: []vmopv1.VirtualMachineNetworkInterfaceSpec{
{
Name: "eth0",
},
{
Name: "eth1",
},
},
}
},
validate: doValidateWithMsg(`spec.network.interfaces: Forbidden: network interfaces cannot be added or removed`),
},
),
Entry("disallow Network Interface Name change",
testParams{
setup: func(ctx *unitValidatingWebhookContext) {
ctx.oldVM.Spec.Network = &vmopv1.VirtualMachineNetworkSpec{
Interfaces: []vmopv1.VirtualMachineNetworkInterfaceSpec{
{
Name: "eth0",
},
},
}
ctx.vm.Spec.Network = &vmopv1.VirtualMachineNetworkSpec{
Interfaces: []vmopv1.VirtualMachineNetworkInterfaceSpec{
{
Name: "eth1",
},
},
}
},
validate: doValidateWithMsg(`spec.network.interfaces[0].name: Forbidden: field is immutable`),
},
),
Entry("disallow Network Interface Network ref change",
testParams{
setup: func(ctx *unitValidatingWebhookContext) {
ctx.oldVM.Spec.Network = &vmopv1.VirtualMachineNetworkSpec{
Interfaces: []vmopv1.VirtualMachineNetworkInterfaceSpec{
{
Name: "eth0",
Network: &common.PartialObjectRef{Name: "net1"},
},
},
}
ctx.vm.Spec.Network = &vmopv1.VirtualMachineNetworkSpec{
Interfaces: []vmopv1.VirtualMachineNetworkInterfaceSpec{
{
Name: "eth0",
Network: &common.PartialObjectRef{Name: "net99"},
},
},
}
},
validate: doValidateWithMsg(`spec.network.interfaces[0].network: Forbidden: field is immutable`),
},
),
)
})
}

func unitTestsValidateDelete() {
Expand Down

0 comments on commit a501746

Please sign in to comment.