sigs.k8s.io/cluster-api-provider-azure@v1.14.3/api/v1beta1/azuremanagedmachinepooltemplate_webhook_test.go (about) 1 /* 2 Copyright 2023 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package v1beta1 18 19 import ( 20 "context" 21 "testing" 22 23 . "github.com/onsi/gomega" 24 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 25 "k8s.io/utils/ptr" 26 azureutil "sigs.k8s.io/cluster-api-provider-azure/util/azure" 27 ) 28 29 func TestManagedMachinePoolTemplateDefaultingWebhook(t *testing.T) { 30 g := NewWithT(t) 31 32 t.Logf("Testing ammpt defaulting webhook with no baseline") 33 ammpt := getAzureManagedMachinePoolTemplate() 34 mmptw := &azureManagedMachinePoolTemplateWebhook{} 35 err := mmptw.Default(context.Background(), ammpt) 36 g.Expect(err).NotTo(HaveOccurred()) 37 g.Expect(ammpt.Labels).To(Equal(map[string]string{ 38 LabelAgentPoolMode: "System", 39 })) 40 g.Expect(ammpt.Spec.Template.Spec.Name).To(Equal(ptr.To("fooName"))) 41 g.Expect(ammpt.Spec.Template.Spec.OSType).To(Equal(ptr.To("Linux"))) 42 43 t.Logf("Testing ammpt defaulting webhook with baseline") 44 ammpt = getAzureManagedMachinePoolTemplate(func(ammpt *AzureManagedMachinePoolTemplate) { 45 ammpt.Spec.Template.Spec.Mode = "User" 46 ammpt.Spec.Template.Spec.Name = ptr.To("barName") 47 ammpt.Spec.Template.Spec.OSType = ptr.To("Windows") 48 }) 49 err = mmptw.Default(context.Background(), ammpt) 50 g.Expect(err).NotTo(HaveOccurred()) 51 g.Expect(ammpt.Labels).To(Equal(map[string]string{ 52 LabelAgentPoolMode: "User", 53 })) 54 g.Expect(ammpt.Spec.Template.Spec.Name).To(Equal(ptr.To("barName"))) 55 g.Expect(ammpt.Spec.Template.Spec.OSType).To(Equal(ptr.To("Windows"))) 56 } 57 58 func TestManagedMachinePoolTemplateUpdateWebhook(t *testing.T) { 59 tests := []struct { 60 name string 61 oldMachinePoolTemplate *AzureManagedMachinePoolTemplate 62 machinePoolTemplate *AzureManagedMachinePoolTemplate 63 wantErr bool 64 }{ 65 { 66 name: "azuremanagedmachinepooltemplate no changes - valid spec", 67 oldMachinePoolTemplate: getAzureManagedMachinePoolTemplate(), 68 machinePoolTemplate: getAzureManagedMachinePoolTemplate(), 69 wantErr: false, 70 }, 71 { 72 name: "azuremanagedmachinepooltemplate name is immutable", 73 oldMachinePoolTemplate: getAzureManagedMachinePoolTemplate(), 74 machinePoolTemplate: getAzureManagedMachinePoolTemplate(func(ammpt *AzureManagedMachinePoolTemplate) { 75 ammpt.Spec.Template.Spec.Name = ptr.To("barName") 76 }), 77 wantErr: true, 78 }, 79 { 80 name: "azuremanagedmachinepooltemplate invalid nodeLabel", 81 oldMachinePoolTemplate: getAzureManagedMachinePoolTemplate(), 82 machinePoolTemplate: getAzureManagedMachinePoolTemplate(func(ammpt *AzureManagedMachinePoolTemplate) { 83 ammpt.Spec.Template.Spec.NodeLabels = map[string]string{ 84 azureutil.AzureSystemNodeLabelPrefix: "foo", 85 } 86 }), 87 wantErr: true, 88 }, 89 { 90 name: "azuremanagedmachinepooltemplate osType is immutable", 91 oldMachinePoolTemplate: getAzureManagedMachinePoolTemplate(func(ammpt *AzureManagedMachinePoolTemplate) { 92 ammpt.Spec.Template.Spec.OSType = ptr.To("Windows") 93 }), 94 machinePoolTemplate: getAzureManagedMachinePoolTemplate(func(ammpt *AzureManagedMachinePoolTemplate) { 95 ammpt.Spec.Template.Spec.OSType = ptr.To("Linux") 96 }), 97 wantErr: true, 98 }, 99 { 100 name: "azuremanagedmachinepooltemplate SKU is immutable", 101 oldMachinePoolTemplate: getAzureManagedMachinePoolTemplate(func(ammpt *AzureManagedMachinePoolTemplate) { 102 ammpt.Spec.Template.Spec.SKU = "Standard_D2s_v3" 103 }), 104 machinePoolTemplate: getAzureManagedMachinePoolTemplate(func(ammpt *AzureManagedMachinePoolTemplate) { 105 ammpt.Spec.Template.Spec.SKU = "Standard_D4s_v3" 106 }), 107 wantErr: true, 108 }, 109 { 110 name: "azuremanagedmachinepooltemplate OSDiskSizeGB is immutable", 111 oldMachinePoolTemplate: getAzureManagedMachinePoolTemplate(func(ammpt *AzureManagedMachinePoolTemplate) { 112 ammpt.Spec.Template.Spec.OSDiskSizeGB = ptr.To(128) 113 }), 114 machinePoolTemplate: getAzureManagedMachinePoolTemplate(func(ammpt *AzureManagedMachinePoolTemplate) { 115 ammpt.Spec.Template.Spec.OSDiskSizeGB = ptr.To(256) 116 }), 117 wantErr: true, 118 }, 119 { 120 name: "azuremanagedmachinepooltemplate SubnetName is immutable", 121 oldMachinePoolTemplate: getAzureManagedMachinePoolTemplate(func(ammpt *AzureManagedMachinePoolTemplate) { 122 ammpt.Spec.Template.Spec.SubnetName = ptr.To("fooSubnet") 123 }), 124 machinePoolTemplate: getAzureManagedMachinePoolTemplate(func(ammpt *AzureManagedMachinePoolTemplate) { 125 ammpt.Spec.Template.Spec.SubnetName = ptr.To("barSubnet") 126 }), 127 wantErr: true, 128 }, 129 { 130 name: "azuremanagedmachinepooltemplate enableFIPS is immutable", 131 oldMachinePoolTemplate: getAzureManagedMachinePoolTemplate(func(ammpt *AzureManagedMachinePoolTemplate) { 132 ammpt.Spec.Template.Spec.EnableFIPS = ptr.To(true) 133 }), 134 machinePoolTemplate: getAzureManagedMachinePoolTemplate(func(ammpt *AzureManagedMachinePoolTemplate) { 135 ammpt.Spec.Template.Spec.EnableFIPS = ptr.To(false) 136 }), 137 wantErr: true, 138 }, 139 { 140 name: "azuremanagedmachinepooltemplate MaxPods is immutable", 141 oldMachinePoolTemplate: getAzureManagedMachinePoolTemplate(func(ammpt *AzureManagedMachinePoolTemplate) { 142 ammpt.Spec.Template.Spec.MaxPods = ptr.To(128) 143 }), 144 machinePoolTemplate: getAzureManagedMachinePoolTemplate(func(ammpt *AzureManagedMachinePoolTemplate) { 145 ammpt.Spec.Template.Spec.MaxPods = ptr.To(256) 146 }), 147 wantErr: true, 148 }, 149 { 150 name: "azuremanagedmachinepooltemplate OSDiskType is immutable", 151 oldMachinePoolTemplate: getAzureManagedMachinePoolTemplate(func(ammpt *AzureManagedMachinePoolTemplate) { 152 ammpt.Spec.Template.Spec.OsDiskType = ptr.To("Standard_LRS") 153 }), 154 machinePoolTemplate: getAzureManagedMachinePoolTemplate(func(ammpt *AzureManagedMachinePoolTemplate) { 155 ammpt.Spec.Template.Spec.OsDiskType = ptr.To("Premium_LRS") 156 }), 157 wantErr: true, 158 }, 159 { 160 name: "azuremanagedmachinepooltemplate scaleSetPriority is immutable", 161 oldMachinePoolTemplate: getAzureManagedMachinePoolTemplate(func(ammpt *AzureManagedMachinePoolTemplate) { 162 ammpt.Spec.Template.Spec.ScaleSetPriority = ptr.To("Regular") 163 }), 164 machinePoolTemplate: getAzureManagedMachinePoolTemplate(func(ammpt *AzureManagedMachinePoolTemplate) { 165 ammpt.Spec.Template.Spec.ScaleSetPriority = ptr.To("Spot") 166 }), 167 wantErr: true, 168 }, 169 { 170 name: "azuremanagedmachinepooltemplate enableUltraSSD is immutable", 171 oldMachinePoolTemplate: getAzureManagedMachinePoolTemplate(func(ammpt *AzureManagedMachinePoolTemplate) { 172 ammpt.Spec.Template.Spec.EnableUltraSSD = ptr.To(true) 173 }), 174 machinePoolTemplate: getAzureManagedMachinePoolTemplate(func(ammpt *AzureManagedMachinePoolTemplate) { 175 ammpt.Spec.Template.Spec.EnableUltraSSD = ptr.To(false) 176 }), 177 wantErr: true, 178 }, 179 { 180 name: "azuremanagedmachinepooltemplate enableNodePublicIP is immutable", 181 oldMachinePoolTemplate: getAzureManagedMachinePoolTemplate(func(ammpt *AzureManagedMachinePoolTemplate) { 182 ammpt.Spec.Template.Spec.EnableNodePublicIP = ptr.To(true) 183 }), 184 machinePoolTemplate: getAzureManagedMachinePoolTemplate(func(ammpt *AzureManagedMachinePoolTemplate) { 185 ammpt.Spec.Template.Spec.EnableNodePublicIP = ptr.To(false) 186 }), 187 wantErr: true, 188 }, 189 { 190 name: "azuremanagedmachinepooltemplate nodePublicIPPrefixID is immutable", 191 oldMachinePoolTemplate: getAzureManagedMachinePoolTemplate(func(ammpt *AzureManagedMachinePoolTemplate) { 192 ammpt.Spec.Template.Spec.NodePublicIPPrefixID = ptr.To("fooPublicIPPrefixID") 193 }), 194 machinePoolTemplate: getAzureManagedMachinePoolTemplate(func(ammpt *AzureManagedMachinePoolTemplate) { 195 ammpt.Spec.Template.Spec.NodePublicIPPrefixID = ptr.To("barPublicIPPrefixID") 196 }), 197 wantErr: true, 198 }, 199 { 200 name: "azuremanagedmachinepooltemplate kubeletConfig is immutable", 201 oldMachinePoolTemplate: getAzureManagedMachinePoolTemplate(func(ammpt *AzureManagedMachinePoolTemplate) { 202 ammpt.Spec.Template.Spec.KubeletConfig = &KubeletConfig{} 203 }), 204 machinePoolTemplate: getAzureManagedMachinePoolTemplate(func(ammpt *AzureManagedMachinePoolTemplate) { 205 ammpt.Spec.Template.Spec.KubeletConfig = &KubeletConfig{ 206 FailSwapOn: ptr.To(true), 207 } 208 }), 209 wantErr: true, 210 }, 211 { 212 name: "azuremanagedmachinepooltemplate kubeletDiskType is immutable", 213 oldMachinePoolTemplate: getAzureManagedMachinePoolTemplate(func(ammpt *AzureManagedMachinePoolTemplate) { 214 ammpt.Spec.Template.Spec.KubeletDiskType = ptr.To(KubeletDiskTypeOS) 215 }), 216 machinePoolTemplate: getAzureManagedMachinePoolTemplate(func(ammpt *AzureManagedMachinePoolTemplate) { 217 ammpt.Spec.Template.Spec.KubeletDiskType = ptr.To(KubeletDiskTypeTemporary) 218 }), 219 wantErr: true, 220 }, 221 { 222 name: "azuremanagedmachinepooltemplate linuxOSConfig is immutable", 223 oldMachinePoolTemplate: getAzureManagedMachinePoolTemplate(func(ammpt *AzureManagedMachinePoolTemplate) { 224 ammpt.Spec.Template.Spec.LinuxOSConfig = &LinuxOSConfig{} 225 }), 226 machinePoolTemplate: getAzureManagedMachinePoolTemplate(func(ammpt *AzureManagedMachinePoolTemplate) { 227 ammpt.Spec.Template.Spec.LinuxOSConfig = &LinuxOSConfig{ 228 SwapFileSizeMB: ptr.To(128), 229 } 230 }), 231 wantErr: true, 232 }, 233 } 234 for _, tc := range tests { 235 t.Run(tc.name, func(t *testing.T) { 236 g := NewWithT(t) 237 mpw := &azureManagedMachinePoolTemplateWebhook{} 238 _, err := mpw.ValidateUpdate(context.Background(), tc.oldMachinePoolTemplate, tc.machinePoolTemplate) 239 if tc.wantErr { 240 g.Expect(err).To(HaveOccurred()) 241 } else { 242 g.Expect(err).NotTo(HaveOccurred()) 243 } 244 }) 245 } 246 } 247 248 func getAzureManagedMachinePoolTemplate(changes ...func(*AzureManagedMachinePoolTemplate)) *AzureManagedMachinePoolTemplate { 249 input := &AzureManagedMachinePoolTemplate{ 250 ObjectMeta: metav1.ObjectMeta{ 251 Name: "fooName", 252 }, 253 Spec: AzureManagedMachinePoolTemplateSpec{ 254 Template: AzureManagedMachinePoolTemplateResource{ 255 Spec: AzureManagedMachinePoolTemplateResourceSpec{ 256 AzureManagedMachinePoolClassSpec: AzureManagedMachinePoolClassSpec{ 257 Mode: "System", 258 }, 259 }, 260 }, 261 }, 262 } 263 264 for _, change := range changes { 265 change(input) 266 } 267 268 return input 269 }