sigs.k8s.io/cluster-api@v1.7.1/bootstrap/kubeadm/types/utils_test.go (about) 1 /* 2 Copyright 2021 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 utils 18 19 import ( 20 "testing" 21 22 "github.com/blang/semver/v4" 23 "github.com/google/go-cmp/cmp" 24 . "github.com/onsi/gomega" 25 "k8s.io/apimachinery/pkg/runtime/schema" 26 27 bootstrapv1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1beta1" 28 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/types/upstreamv1beta2" 29 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/types/upstreamv1beta3" 30 ) 31 32 func TestKubeVersionToKubeadmAPIGroupVersion(t *testing.T) { 33 type args struct { 34 version semver.Version 35 } 36 tests := []struct { 37 name string 38 args args 39 want schema.GroupVersion 40 wantErr bool 41 }{ 42 { 43 name: "fails when kubernetes version is too old", 44 args: args{ 45 version: semver.MustParse("1.12.0"), 46 }, 47 want: schema.GroupVersion{}, 48 wantErr: true, 49 }, 50 { 51 name: "fails with kubernetes version for kubeadm API v1beta1", 52 args: args{ 53 version: semver.MustParse("1.14.99"), 54 }, 55 wantErr: true, 56 }, 57 { 58 name: "pass with minimum kubernetes alpha version for kubeadm API v1beta2", 59 args: args{ 60 version: semver.MustParse("1.15.0-alpha.0.734+ba502ee555924a"), 61 }, 62 want: upstreamv1beta2.GroupVersion, 63 wantErr: false, 64 }, 65 { 66 name: "pass with minimum kubernetes version for kubeadm API v1beta2", 67 args: args{ 68 version: semver.MustParse("1.15.0"), 69 }, 70 want: upstreamv1beta2.GroupVersion, 71 wantErr: false, 72 }, 73 { 74 name: "pass with kubernetes version for kubeadm API v1beta2", 75 args: args{ 76 version: semver.MustParse("1.20.99"), 77 }, 78 want: upstreamv1beta2.GroupVersion, 79 wantErr: false, 80 }, 81 { 82 name: "pass with minimum kubernetes alpha version for kubeadm API v1beta3", 83 args: args{ 84 version: semver.MustParse("1.22.0-alpha.0.734+ba502ee555924a"), 85 }, 86 want: upstreamv1beta3.GroupVersion, 87 wantErr: false, 88 }, 89 { 90 name: "pass with minimum kubernetes version for kubeadm API v1beta3", 91 args: args{ 92 version: semver.MustParse("1.22.0"), 93 }, 94 want: upstreamv1beta3.GroupVersion, 95 wantErr: false, 96 }, 97 { 98 name: "pass with kubernetes version for kubeadm API v1beta3", 99 args: args{ 100 version: semver.MustParse("1.23.99"), 101 }, 102 want: upstreamv1beta3.GroupVersion, 103 wantErr: false, 104 }, 105 { 106 name: "pass with future kubernetes version", 107 args: args{ 108 version: semver.MustParse("99.99.99"), 109 }, 110 want: upstreamv1beta3.GroupVersion, 111 wantErr: false, 112 }, 113 } 114 for _, tt := range tests { 115 t.Run(tt.name, func(t *testing.T) { 116 g := NewWithT(t) 117 118 got, err := KubeVersionToKubeadmAPIGroupVersion(tt.args.version) 119 if tt.wantErr { 120 g.Expect(err).To(HaveOccurred()) 121 return 122 } 123 g.Expect(err).ToNot(HaveOccurred()) 124 g.Expect(got).To(BeComparableTo(tt.want)) 125 }) 126 } 127 } 128 129 func TestMarshalClusterConfigurationForVersion(t *testing.T) { 130 type args struct { 131 capiObj *bootstrapv1.ClusterConfiguration 132 version semver.Version 133 } 134 tests := []struct { 135 name string 136 args args 137 want string 138 wantErr bool 139 }{ 140 { 141 name: "Generates a v1beta2 kubeadm configuration", 142 args: args{ 143 capiObj: &bootstrapv1.ClusterConfiguration{}, 144 version: semver.MustParse("1.15.0"), 145 }, 146 want: "apiServer: {}\n" + 147 "apiVersion: kubeadm.k8s.io/v1beta2\n" + "" + 148 "controllerManager: {}\n" + 149 "dns: {}\n" + 150 "etcd: {}\n" + 151 "kind: ClusterConfiguration\n" + 152 "networking: {}\n" + 153 "scheduler: {}\n", 154 wantErr: false, 155 }, 156 { 157 name: "Generates a v1beta3 kubeadm configuration", 158 args: args{ 159 capiObj: &bootstrapv1.ClusterConfiguration{}, 160 version: semver.MustParse("1.22.0"), 161 }, 162 want: "apiServer: {}\n" + 163 "apiVersion: kubeadm.k8s.io/v1beta3\n" + "" + 164 "controllerManager: {}\n" + 165 "dns: {}\n" + 166 "etcd: {}\n" + 167 "kind: ClusterConfiguration\n" + 168 "networking: {}\n" + 169 "scheduler: {}\n", 170 wantErr: false, 171 }, 172 } 173 for _, tt := range tests { 174 t.Run(tt.name, func(t *testing.T) { 175 g := NewWithT(t) 176 177 got, err := MarshalClusterConfigurationForVersion(tt.args.capiObj, tt.args.version) 178 if tt.wantErr { 179 g.Expect(err).To(HaveOccurred()) 180 return 181 } 182 g.Expect(err).ToNot(HaveOccurred()) 183 g.Expect(got).To(Equal(tt.want), cmp.Diff(tt.want, got)) 184 }) 185 } 186 } 187 188 func TestMarshalClusterStatusForVersion(t *testing.T) { 189 type args struct { 190 capiObj *bootstrapv1.ClusterStatus 191 version semver.Version 192 } 193 tests := []struct { 194 name string 195 args args 196 want string 197 wantErr bool 198 }{ 199 { 200 name: "Generates a v1beta2 kubeadm status", 201 args: args{ 202 capiObj: &bootstrapv1.ClusterStatus{}, 203 version: semver.MustParse("1.15.0"), 204 }, 205 want: "apiEndpoints: null\n" + 206 "apiVersion: kubeadm.k8s.io/v1beta2\n" + "" + 207 "kind: ClusterStatus\n", 208 wantErr: false, 209 }, 210 { 211 name: "Fails generating a v1beta3 kubeadm status", 212 args: args{ 213 capiObj: &bootstrapv1.ClusterStatus{}, 214 version: semver.MustParse("1.22.0"), 215 }, 216 wantErr: true, 217 }, 218 } 219 for _, tt := range tests { 220 t.Run(tt.name, func(t *testing.T) { 221 g := NewWithT(t) 222 223 got, err := MarshalClusterStatusForVersion(tt.args.capiObj, tt.args.version) 224 if tt.wantErr { 225 g.Expect(err).To(HaveOccurred()) 226 return 227 } 228 g.Expect(err).ToNot(HaveOccurred()) 229 g.Expect(got).To(Equal(tt.want), cmp.Diff(tt.want, got)) 230 }) 231 } 232 } 233 234 func TestMarshalInitConfigurationForVersion(t *testing.T) { 235 type args struct { 236 capiObj *bootstrapv1.InitConfiguration 237 version semver.Version 238 } 239 tests := []struct { 240 name string 241 args args 242 want string 243 wantErr bool 244 }{ 245 { 246 name: "Generates a v1beta2 kubeadm configuration", 247 args: args{ 248 capiObj: &bootstrapv1.InitConfiguration{ 249 NodeRegistration: bootstrapv1.NodeRegistrationOptions{ 250 IgnorePreflightErrors: []string{"some-preflight-check"}, 251 }, 252 }, 253 version: semver.MustParse("1.15.0"), 254 }, 255 want: "apiVersion: kubeadm.k8s.io/v1beta2\n" + 256 "kind: InitConfiguration\n" + 257 "localAPIEndpoint: {}\n" + 258 "nodeRegistration:\n" + 259 " ignorePreflightErrors:\n" + 260 " - some-preflight-check\n", 261 wantErr: false, 262 }, 263 { 264 name: "Generates a v1beta3 kubeadm configuration", 265 args: args{ 266 capiObj: &bootstrapv1.InitConfiguration{ 267 NodeRegistration: bootstrapv1.NodeRegistrationOptions{ 268 IgnorePreflightErrors: []string{"some-preflight-check"}, 269 }, 270 }, 271 version: semver.MustParse("1.22.0"), 272 }, 273 want: "apiVersion: kubeadm.k8s.io/v1beta3\n" + 274 "kind: InitConfiguration\n" + 275 "localAPIEndpoint: {}\n" + 276 "nodeRegistration:\n" + 277 " ignorePreflightErrors:\n" + 278 " - some-preflight-check\n" + 279 " taints: null\n", 280 wantErr: false, 281 }, 282 } 283 for _, tt := range tests { 284 t.Run(tt.name, func(t *testing.T) { 285 g := NewWithT(t) 286 287 got, err := MarshalInitConfigurationForVersion(tt.args.capiObj, tt.args.version) 288 if tt.wantErr { 289 g.Expect(err).To(HaveOccurred()) 290 return 291 } 292 g.Expect(err).ToNot(HaveOccurred()) 293 g.Expect(got).To(Equal(tt.want), cmp.Diff(tt.want, got)) 294 }) 295 } 296 } 297 298 func TestMarshalJoinConfigurationForVersion(t *testing.T) { 299 type args struct { 300 capiObj *bootstrapv1.JoinConfiguration 301 version semver.Version 302 } 303 tests := []struct { 304 name string 305 args args 306 want string 307 wantErr bool 308 }{ 309 { 310 name: "Generates a v1beta2 kubeadm configuration", 311 args: args{ 312 capiObj: &bootstrapv1.JoinConfiguration{ 313 NodeRegistration: bootstrapv1.NodeRegistrationOptions{ 314 IgnorePreflightErrors: []string{"some-preflight-check"}, 315 }, 316 }, 317 version: semver.MustParse("1.15.0"), 318 }, 319 want: "apiVersion: kubeadm.k8s.io/v1beta2\n" + "" + 320 "discovery: {}\n" + 321 "kind: JoinConfiguration\n" + 322 "nodeRegistration:\n" + 323 " ignorePreflightErrors:\n" + 324 " - some-preflight-check\n", 325 wantErr: false, 326 }, 327 { 328 name: "Generates a v1beta3 kubeadm configuration", 329 args: args{ 330 capiObj: &bootstrapv1.JoinConfiguration{ 331 NodeRegistration: bootstrapv1.NodeRegistrationOptions{ 332 IgnorePreflightErrors: []string{"some-preflight-check"}, 333 }, 334 }, 335 version: semver.MustParse("1.22.0"), 336 }, 337 want: "apiVersion: kubeadm.k8s.io/v1beta3\n" + "" + 338 "discovery: {}\n" + 339 "kind: JoinConfiguration\n" + 340 "nodeRegistration:\n" + 341 " ignorePreflightErrors:\n" + 342 " - some-preflight-check\n" + 343 " taints: null\n", 344 wantErr: false, 345 }, 346 } 347 for _, tt := range tests { 348 t.Run(tt.name, func(t *testing.T) { 349 g := NewWithT(t) 350 351 got, err := MarshalJoinConfigurationForVersion(tt.args.capiObj, tt.args.version) 352 if tt.wantErr { 353 g.Expect(err).To(HaveOccurred()) 354 return 355 } 356 g.Expect(err).ToNot(HaveOccurred()) 357 g.Expect(got).To(Equal(tt.want), cmp.Diff(tt.want, got)) 358 }) 359 } 360 } 361 362 func TestUnmarshalClusterConfiguration(t *testing.T) { 363 type args struct { 364 yaml string 365 } 366 tests := []struct { 367 name string 368 args args 369 want *bootstrapv1.ClusterConfiguration 370 wantErr bool 371 }{ 372 { 373 name: "Parses a v1beta2 kubeadm configuration", 374 args: args{ 375 yaml: "apiServer: {}\n" + 376 "apiVersion: kubeadm.k8s.io/v1beta2\n" + "" + 377 "controllerManager: {}\n" + 378 "dns: {}\n" + 379 "etcd: {}\n" + 380 "kind: ClusterConfiguration\n" + 381 "networking: {}\n" + 382 "scheduler: {}\n", 383 }, 384 want: &bootstrapv1.ClusterConfiguration{}, 385 wantErr: false, 386 }, 387 { 388 name: "Parses a v1beta3 kubeadm configuration", 389 args: args{ 390 yaml: "apiServer: {}\n" + 391 "apiVersion: kubeadm.k8s.io/v1beta3\n" + "" + 392 "controllerManager: {}\n" + 393 "dns: {}\n" + 394 "etcd: {}\n" + 395 "kind: ClusterConfiguration\n" + 396 "networking: {}\n" + 397 "scheduler: {}\n", 398 }, 399 want: &bootstrapv1.ClusterConfiguration{}, 400 wantErr: false, 401 }, 402 } 403 for _, tt := range tests { 404 t.Run(tt.name, func(t *testing.T) { 405 g := NewWithT(t) 406 407 got, err := UnmarshalClusterConfiguration(tt.args.yaml) 408 if tt.wantErr { 409 g.Expect(err).To(HaveOccurred()) 410 return 411 } 412 g.Expect(err).ToNot(HaveOccurred()) 413 g.Expect(got).To(BeComparableTo(tt.want), cmp.Diff(tt.want, got)) 414 }) 415 } 416 } 417 418 func TestUnmarshalClusterStatus(t *testing.T) { 419 type args struct { 420 yaml string 421 } 422 tests := []struct { 423 name string 424 args args 425 want *bootstrapv1.ClusterStatus 426 wantErr bool 427 }{ 428 { 429 name: "Parses a v1beta2 kubeadm configuration", 430 args: args{ 431 yaml: "apiEndpoints: null\n" + 432 "apiVersion: kubeadm.k8s.io/v1beta2\n" + "" + 433 "kind: ClusterStatus\n", 434 }, 435 want: &bootstrapv1.ClusterStatus{}, 436 wantErr: false, 437 }, 438 { 439 name: "Fails parsing a v1beta3 kubeadm configuration", 440 args: args{ 441 yaml: "apiEndpoints: null\n" + 442 "apiVersion: kubeadm.k8s.io/v1beta3\n" + "" + 443 "kind: ClusterStatus\n", 444 }, 445 wantErr: true, 446 }, 447 } 448 for _, tt := range tests { 449 t.Run(tt.name, func(t *testing.T) { 450 g := NewWithT(t) 451 452 got, err := UnmarshalClusterStatus(tt.args.yaml) 453 if tt.wantErr { 454 g.Expect(err).To(HaveOccurred()) 455 return 456 } 457 g.Expect(err).ToNot(HaveOccurred()) 458 g.Expect(got).To(BeComparableTo(tt.want), cmp.Diff(tt.want, got)) 459 }) 460 } 461 } 462 463 func TestUnmarshalInitConfiguration(t *testing.T) { 464 type args struct { 465 yaml string 466 } 467 tests := []struct { 468 name string 469 args args 470 want *bootstrapv1.InitConfiguration 471 wantErr bool 472 }{ 473 { 474 name: "Parses a v1beta2 kubeadm configuration", 475 args: args{ 476 yaml: "apiVersion: kubeadm.k8s.io/v1beta2\n" + "" + 477 "kind: InitConfiguration\n" + 478 "localAPIEndpoint: {}\n" + 479 "nodeRegistration: {}\n", 480 }, 481 want: &bootstrapv1.InitConfiguration{}, 482 wantErr: false, 483 }, 484 { 485 name: "Parses a v1beta3 kubeadm configuration", 486 args: args{ 487 yaml: "apiVersion: kubeadm.k8s.io/v1beta3\n" + "" + 488 "kind: InitConfiguration\n" + 489 "localAPIEndpoint: {}\n" + 490 "nodeRegistration: {}\n", 491 }, 492 want: &bootstrapv1.InitConfiguration{}, 493 wantErr: false, 494 }, 495 } 496 for _, tt := range tests { 497 t.Run(tt.name, func(t *testing.T) { 498 g := NewWithT(t) 499 500 got, err := UnmarshalInitConfiguration(tt.args.yaml) 501 if tt.wantErr { 502 g.Expect(err).To(HaveOccurred()) 503 return 504 } 505 g.Expect(err).ToNot(HaveOccurred()) 506 g.Expect(got).To(BeComparableTo(tt.want), cmp.Diff(tt.want, got)) 507 }) 508 } 509 } 510 511 func TestUnmarshalJoinConfiguration(t *testing.T) { 512 type args struct { 513 yaml string 514 } 515 tests := []struct { 516 name string 517 args args 518 want *bootstrapv1.JoinConfiguration 519 wantErr bool 520 }{ 521 { 522 name: "Parses a v1beta2 kubeadm configuration", 523 args: args{ 524 yaml: "apiVersion: kubeadm.k8s.io/v1beta2\n" + "" + 525 "caCertPath: \"\"\n" + 526 "discovery: {}\n" + 527 "kind: JoinConfiguration\n", 528 }, 529 want: &bootstrapv1.JoinConfiguration{}, 530 wantErr: false, 531 }, 532 { 533 name: "Parses a v1beta3 kubeadm configuration", 534 args: args{ 535 yaml: "apiVersion: kubeadm.k8s.io/v1beta3\n" + "" + 536 "caCertPath: \"\"\n" + 537 "discovery: {}\n" + 538 "kind: JoinConfiguration\n", 539 }, 540 want: &bootstrapv1.JoinConfiguration{}, 541 wantErr: false, 542 }, 543 } 544 for _, tt := range tests { 545 t.Run(tt.name, func(t *testing.T) { 546 g := NewWithT(t) 547 548 got, err := UnmarshalJoinConfiguration(tt.args.yaml) 549 if tt.wantErr { 550 g.Expect(err).To(HaveOccurred()) 551 return 552 } 553 g.Expect(err).ToNot(HaveOccurred()) 554 g.Expect(got).To(BeComparableTo(tt.want), cmp.Diff(tt.want, got)) 555 }) 556 } 557 }