1/* 2Copyright 2018 The Kubernetes Authors. 3 4Licensed under the Apache License, Version 2.0 (the "License"); 5you may not use this file except in compliance with the License. 6You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10Unless required by applicable law or agreed to in writing, software 11distributed under the License is distributed on an "AS IS" BASIS, 12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13See the License for the specific language governing permissions and 14limitations under the License. 15*/ 16 17package envtest 18 19import ( 20 "context" 21 "path/filepath" 22 "time" 23 24 . "github.com/onsi/ginkgo" 25 . "github.com/onsi/gomega" 26 apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" 27 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" 28 apierrors "k8s.io/apimachinery/pkg/api/errors" 29 "k8s.io/apimachinery/pkg/runtime" 30 "k8s.io/apimachinery/pkg/types" 31 "sigs.k8s.io/controller-runtime/pkg/client" 32) 33 34var _ = Describe("Test", func() { 35 var crds []runtime.Object 36 var err error 37 var s *runtime.Scheme 38 var c client.Client 39 40 var validDirectory = filepath.Join(".", "testdata") 41 var invalidDirectory = "fake" 42 43 var teardownTimeoutSeconds float64 = 10 44 45 // Initialize the client 46 BeforeEach(func(done Done) { 47 crds = []runtime.Object{} 48 s = runtime.NewScheme() 49 err = v1beta1.AddToScheme(s) 50 Expect(err).NotTo(HaveOccurred()) 51 err = apiextensionsv1.AddToScheme(s) 52 Expect(err).NotTo(HaveOccurred()) 53 54 c, err = client.New(env.Config, client.Options{Scheme: s}) 55 Expect(err).NotTo(HaveOccurred()) 56 57 close(done) 58 }) 59 60 // Cleanup CRDs 61 AfterEach(func(done Done) { 62 for _, crd := range runtimeCRDListToUnstructured(crds) { 63 // Delete only if CRD exists. 64 crdObjectKey := client.ObjectKey{ 65 Name: crd.GetName(), 66 } 67 var placeholder v1beta1.CustomResourceDefinition 68 err := c.Get(context.TODO(), crdObjectKey, &placeholder) 69 if err != nil && apierrors.IsNotFound(err) { 70 // CRD doesn't need to be deleted. 71 continue 72 } 73 Expect(err).NotTo(HaveOccurred()) 74 Expect(c.Delete(context.TODO(), crd)).To(Succeed()) 75 Eventually(func() bool { 76 err := c.Get(context.TODO(), crdObjectKey, &placeholder) 77 return apierrors.IsNotFound(err) 78 }, 1*time.Second).Should(BeTrue()) 79 } 80 close(done) 81 }, teardownTimeoutSeconds) 82 83 Describe("InstallCRDs", func() { 84 It("should install the CRDs into the cluster using directory", func(done Done) { 85 crds, err = InstallCRDs(env.Config, CRDInstallOptions{ 86 Paths: []string{validDirectory}, 87 }) 88 Expect(err).NotTo(HaveOccurred()) 89 90 // Expect to find the CRDs 91 92 crdv1 := &apiextensionsv1.CustomResourceDefinition{} 93 err = c.Get(context.TODO(), types.NamespacedName{Name: "foos.bar.example.com"}, crdv1) 94 Expect(err).NotTo(HaveOccurred()) 95 Expect(crdv1.Spec.Names.Kind).To(Equal("Foo")) 96 97 crd := &v1beta1.CustomResourceDefinition{} 98 err = c.Get(context.TODO(), types.NamespacedName{Name: "bazs.qux.example.com"}, crd) 99 Expect(err).NotTo(HaveOccurred()) 100 Expect(crd.Spec.Names.Kind).To(Equal("Baz")) 101 102 crd = &v1beta1.CustomResourceDefinition{} 103 err = c.Get(context.TODO(), types.NamespacedName{Name: "captains.crew.example.com"}, crd) 104 Expect(err).NotTo(HaveOccurred()) 105 Expect(crd.Spec.Names.Kind).To(Equal("Captain")) 106 107 crd = &v1beta1.CustomResourceDefinition{} 108 err = c.Get(context.TODO(), types.NamespacedName{Name: "firstmates.crew.example.com"}, crd) 109 Expect(err).NotTo(HaveOccurred()) 110 Expect(crd.Spec.Names.Kind).To(Equal("FirstMate")) 111 112 crd = &v1beta1.CustomResourceDefinition{} 113 err = c.Get(context.TODO(), types.NamespacedName{Name: "drivers.crew.example.com"}, crd) 114 Expect(err).NotTo(HaveOccurred()) 115 Expect(crd.Spec.Names.Kind).To(Equal("Driver")) 116 117 err = WaitForCRDs(env.Config, []runtime.Object{ 118 &apiextensionsv1.CustomResourceDefinition{ 119 Spec: apiextensionsv1.CustomResourceDefinitionSpec{ 120 Group: "bar.example.com", 121 Versions: []apiextensionsv1.CustomResourceDefinitionVersion{ 122 { 123 Name: "v1", 124 Storage: true, 125 Served: true, 126 Schema: &apiextensionsv1.CustomResourceValidation{ 127 OpenAPIV3Schema: &apiextensionsv1.JSONSchemaProps{ 128 Type: "object", 129 }, 130 }, 131 }, 132 }, 133 Names: apiextensionsv1.CustomResourceDefinitionNames{ 134 Plural: "foos", 135 }}, 136 }, 137 &v1beta1.CustomResourceDefinition{ 138 Spec: v1beta1.CustomResourceDefinitionSpec{ 139 Group: "qux.example.com", 140 Version: "v1beta1", 141 Names: v1beta1.CustomResourceDefinitionNames{ 142 Plural: "bazs", 143 }}, 144 }, 145 &v1beta1.CustomResourceDefinition{ 146 Spec: v1beta1.CustomResourceDefinitionSpec{ 147 Group: "crew.example.com", 148 Version: "v1beta1", 149 Names: v1beta1.CustomResourceDefinitionNames{ 150 Plural: "captains", 151 }}, 152 }, 153 &v1beta1.CustomResourceDefinition{ 154 Spec: v1beta1.CustomResourceDefinitionSpec{ 155 Group: "crew.example.com", 156 Version: "v1beta1", 157 Names: v1beta1.CustomResourceDefinitionNames{ 158 Plural: "firstmates", 159 }}, 160 }, 161 &v1beta1.CustomResourceDefinition{ 162 Spec: v1beta1.CustomResourceDefinitionSpec{ 163 Group: "crew.example.com", 164 Names: v1beta1.CustomResourceDefinitionNames{ 165 Plural: "drivers", 166 }, 167 Versions: []v1beta1.CustomResourceDefinitionVersion{ 168 { 169 Name: "v1", 170 Storage: true, 171 Served: true, 172 }, 173 { 174 Name: "v2", 175 Storage: false, 176 Served: true, 177 }, 178 }}, 179 }, 180 }, 181 CRDInstallOptions{MaxTime: 50 * time.Millisecond, PollInterval: 15 * time.Millisecond}, 182 ) 183 Expect(err).NotTo(HaveOccurred()) 184 185 close(done) 186 }, 5) 187 188 It("should install the CRDs into the cluster using file", func(done Done) { 189 crds, err = InstallCRDs(env.Config, CRDInstallOptions{ 190 Paths: []string{filepath.Join(".", "testdata", "crds", "examplecrd3.yaml")}, 191 }) 192 Expect(err).NotTo(HaveOccurred()) 193 194 crd := &v1beta1.CustomResourceDefinition{} 195 err = c.Get(context.TODO(), types.NamespacedName{Name: "configs.foo.example.com"}, crd) 196 Expect(err).NotTo(HaveOccurred()) 197 Expect(crd.Spec.Names.Kind).To(Equal("Config")) 198 199 err = WaitForCRDs(env.Config, []runtime.Object{ 200 &v1beta1.CustomResourceDefinition{ 201 Spec: v1beta1.CustomResourceDefinitionSpec{ 202 Group: "foo.example.com", 203 Version: "v1beta1", 204 Names: v1beta1.CustomResourceDefinitionNames{ 205 Plural: "configs", 206 }}, 207 }, 208 }, 209 CRDInstallOptions{MaxTime: 50 * time.Millisecond, PollInterval: 15 * time.Millisecond}, 210 ) 211 Expect(err).NotTo(HaveOccurred()) 212 213 close(done) 214 }, 10) 215 216 It("should filter out already existent CRD", func(done Done) { 217 crds, err = InstallCRDs(env.Config, CRDInstallOptions{ 218 Paths: []string{ 219 filepath.Join(".", "testdata"), 220 filepath.Join(".", "testdata", "examplecrd1.yaml"), 221 }, 222 }) 223 Expect(err).NotTo(HaveOccurred()) 224 225 crd := &apiextensionsv1.CustomResourceDefinition{} 226 err = c.Get(context.TODO(), types.NamespacedName{Name: "foos.bar.example.com"}, crd) 227 Expect(err).NotTo(HaveOccurred()) 228 Expect(crd.Spec.Names.Kind).To(Equal("Foo")) 229 230 err = WaitForCRDs(env.Config, []runtime.Object{ 231 &apiextensionsv1.CustomResourceDefinition{ 232 Spec: apiextensionsv1.CustomResourceDefinitionSpec{ 233 Group: "bar.example.com", 234 Versions: []apiextensionsv1.CustomResourceDefinitionVersion{ 235 { 236 Name: "v1", 237 Storage: true, 238 Served: true, 239 Schema: &apiextensionsv1.CustomResourceValidation{ 240 OpenAPIV3Schema: &apiextensionsv1.JSONSchemaProps{ 241 Type: "object", 242 }, 243 }, 244 }, 245 }, 246 Names: apiextensionsv1.CustomResourceDefinitionNames{ 247 Plural: "foos", 248 }}, 249 }, 250 }, 251 CRDInstallOptions{MaxTime: 50 * time.Millisecond, PollInterval: 15 * time.Millisecond}, 252 ) 253 Expect(err).NotTo(HaveOccurred()) 254 255 close(done) 256 }, 10) 257 258 It("should not return an not error if the directory doesn't exist", func(done Done) { 259 crds, err = InstallCRDs(env.Config, CRDInstallOptions{Paths: []string{invalidDirectory}}) 260 Expect(err).NotTo(HaveOccurred()) 261 262 close(done) 263 }, 5) 264 265 It("should return an error if the directory doesn't exist", func(done Done) { 266 crds, err = InstallCRDs(env.Config, CRDInstallOptions{ 267 Paths: []string{invalidDirectory}, ErrorIfPathMissing: true, 268 }) 269 Expect(err).To(HaveOccurred()) 270 271 close(done) 272 }, 5) 273 274 It("should return an error if the file doesn't exist", func(done Done) { 275 crds, err = InstallCRDs(env.Config, CRDInstallOptions{Paths: []string{ 276 filepath.Join(".", "testdata", "fake.yaml")}, ErrorIfPathMissing: true, 277 }) 278 Expect(err).To(HaveOccurred()) 279 280 close(done) 281 }, 5) 282 283 It("should return an error if the resource group version isn't found", func(done Done) { 284 // Wait for a CRD where the Group and Version don't exist 285 err := WaitForCRDs(env.Config, 286 []runtime.Object{ 287 &v1beta1.CustomResourceDefinition{ 288 Spec: v1beta1.CustomResourceDefinitionSpec{ 289 Version: "v1", 290 Names: v1beta1.CustomResourceDefinitionNames{ 291 Plural: "notfound", 292 }}, 293 }, 294 }, 295 CRDInstallOptions{MaxTime: 50 * time.Millisecond, PollInterval: 15 * time.Millisecond}, 296 ) 297 Expect(err).To(HaveOccurred()) 298 299 close(done) 300 }, 5) 301 302 It("should return an error if the resource isn't found in the group version", func(done Done) { 303 crds, err = InstallCRDs(env.Config, CRDInstallOptions{ 304 Paths: []string{"."}, 305 }) 306 Expect(err).NotTo(HaveOccurred()) 307 308 // Wait for a CRD that doesn't exist, but the Group and Version do 309 err = WaitForCRDs(env.Config, []runtime.Object{ 310 &v1beta1.CustomResourceDefinition{ 311 Spec: v1beta1.CustomResourceDefinitionSpec{ 312 Group: "qux.example.com", 313 Version: "v1beta1", 314 Names: v1beta1.CustomResourceDefinitionNames{ 315 Plural: "bazs", 316 }}, 317 }, 318 &v1beta1.CustomResourceDefinition{ 319 Spec: v1beta1.CustomResourceDefinitionSpec{ 320 Group: "bar.example.com", 321 Version: "v1beta1", 322 Names: v1beta1.CustomResourceDefinitionNames{ 323 Plural: "fake", 324 }}, 325 }}, 326 CRDInstallOptions{MaxTime: 50 * time.Millisecond, PollInterval: 15 * time.Millisecond}, 327 ) 328 Expect(err).To(HaveOccurred()) 329 330 close(done) 331 }, 5) 332 333 It("should reinstall the CRDs if already present in the cluster", func(done Done) { 334 335 crds, err = InstallCRDs(env.Config, CRDInstallOptions{ 336 Paths: []string{filepath.Join(".", "testdata")}, 337 }) 338 Expect(err).NotTo(HaveOccurred()) 339 340 // Expect to find the CRDs 341 342 crd := &v1beta1.CustomResourceDefinition{} 343 err = c.Get(context.TODO(), types.NamespacedName{Name: "foos.bar.example.com"}, crd) 344 Expect(err).NotTo(HaveOccurred()) 345 Expect(crd.Spec.Names.Kind).To(Equal("Foo")) 346 347 crd = &v1beta1.CustomResourceDefinition{} 348 err = c.Get(context.TODO(), types.NamespacedName{Name: "bazs.qux.example.com"}, crd) 349 Expect(err).NotTo(HaveOccurred()) 350 Expect(crd.Spec.Names.Kind).To(Equal("Baz")) 351 352 crd = &v1beta1.CustomResourceDefinition{} 353 err = c.Get(context.TODO(), types.NamespacedName{Name: "captains.crew.example.com"}, crd) 354 Expect(err).NotTo(HaveOccurred()) 355 Expect(crd.Spec.Names.Kind).To(Equal("Captain")) 356 357 crd = &v1beta1.CustomResourceDefinition{} 358 err = c.Get(context.TODO(), types.NamespacedName{Name: "firstmates.crew.example.com"}, crd) 359 Expect(err).NotTo(HaveOccurred()) 360 Expect(crd.Spec.Names.Kind).To(Equal("FirstMate")) 361 362 crd = &v1beta1.CustomResourceDefinition{} 363 err = c.Get(context.TODO(), types.NamespacedName{Name: "drivers.crew.example.com"}, crd) 364 Expect(err).NotTo(HaveOccurred()) 365 Expect(crd.Spec.Names.Kind).To(Equal("Driver")) 366 367 err = WaitForCRDs(env.Config, []runtime.Object{ 368 &apiextensionsv1.CustomResourceDefinition{ 369 Spec: apiextensionsv1.CustomResourceDefinitionSpec{ 370 Group: "bar.example.com", 371 Versions: []apiextensionsv1.CustomResourceDefinitionVersion{ 372 { 373 Name: "v1", 374 Storage: true, 375 Served: true, 376 Schema: &apiextensionsv1.CustomResourceValidation{ 377 OpenAPIV3Schema: &apiextensionsv1.JSONSchemaProps{ 378 Type: "object", 379 }, 380 }, 381 }, 382 }, 383 Names: apiextensionsv1.CustomResourceDefinitionNames{ 384 Plural: "foos", 385 }}, 386 }, 387 &v1beta1.CustomResourceDefinition{ 388 Spec: v1beta1.CustomResourceDefinitionSpec{ 389 Group: "qux.example.com", 390 Version: "v1beta1", 391 Names: v1beta1.CustomResourceDefinitionNames{ 392 Plural: "bazs", 393 }}, 394 }, 395 &v1beta1.CustomResourceDefinition{ 396 Spec: v1beta1.CustomResourceDefinitionSpec{ 397 Group: "crew.example.com", 398 Version: "v1beta1", 399 Names: v1beta1.CustomResourceDefinitionNames{ 400 Plural: "captains", 401 }}, 402 }, 403 &v1beta1.CustomResourceDefinition{ 404 Spec: v1beta1.CustomResourceDefinitionSpec{ 405 Group: "crew.example.com", 406 Version: "v1beta1", 407 Names: v1beta1.CustomResourceDefinitionNames{ 408 Plural: "firstmates", 409 }}, 410 }, 411 &v1beta1.CustomResourceDefinition{ 412 Spec: v1beta1.CustomResourceDefinitionSpec{ 413 Group: "crew.example.com", 414 Names: v1beta1.CustomResourceDefinitionNames{ 415 Plural: "drivers", 416 }, 417 Versions: []v1beta1.CustomResourceDefinitionVersion{ 418 { 419 Name: "v1", 420 Storage: true, 421 Served: true, 422 }, 423 { 424 Name: "v2", 425 Storage: false, 426 Served: true, 427 }, 428 }}, 429 }, 430 }, 431 CRDInstallOptions{MaxTime: 50 * time.Millisecond, PollInterval: 15 * time.Millisecond}, 432 ) 433 Expect(err).NotTo(HaveOccurred()) 434 435 // Try to re-install the CRDs 436 437 crds, err = InstallCRDs(env.Config, CRDInstallOptions{ 438 Paths: []string{filepath.Join(".", "testdata")}, 439 }) 440 Expect(err).NotTo(HaveOccurred()) 441 442 // Expect to find the CRDs 443 444 crd = &v1beta1.CustomResourceDefinition{} 445 err = c.Get(context.TODO(), types.NamespacedName{Name: "foos.bar.example.com"}, crd) 446 Expect(err).NotTo(HaveOccurred()) 447 Expect(crd.Spec.Names.Kind).To(Equal("Foo")) 448 449 crd = &v1beta1.CustomResourceDefinition{} 450 err = c.Get(context.TODO(), types.NamespacedName{Name: "bazs.qux.example.com"}, crd) 451 Expect(err).NotTo(HaveOccurred()) 452 Expect(crd.Spec.Names.Kind).To(Equal("Baz")) 453 454 crd = &v1beta1.CustomResourceDefinition{} 455 err = c.Get(context.TODO(), types.NamespacedName{Name: "captains.crew.example.com"}, crd) 456 Expect(err).NotTo(HaveOccurred()) 457 Expect(crd.Spec.Names.Kind).To(Equal("Captain")) 458 459 crd = &v1beta1.CustomResourceDefinition{} 460 err = c.Get(context.TODO(), types.NamespacedName{Name: "firstmates.crew.example.com"}, crd) 461 Expect(err).NotTo(HaveOccurred()) 462 Expect(crd.Spec.Names.Kind).To(Equal("FirstMate")) 463 464 crd = &v1beta1.CustomResourceDefinition{} 465 err = c.Get(context.TODO(), types.NamespacedName{Name: "drivers.crew.example.com"}, crd) 466 Expect(err).NotTo(HaveOccurred()) 467 Expect(crd.Spec.Names.Kind).To(Equal("Driver")) 468 469 err = WaitForCRDs(env.Config, []runtime.Object{ 470 &apiextensionsv1.CustomResourceDefinition{ 471 Spec: apiextensionsv1.CustomResourceDefinitionSpec{ 472 Group: "bar.example.com", 473 Versions: []apiextensionsv1.CustomResourceDefinitionVersion{ 474 { 475 Name: "v1", 476 Storage: true, 477 Served: true, 478 Schema: &apiextensionsv1.CustomResourceValidation{ 479 OpenAPIV3Schema: &apiextensionsv1.JSONSchemaProps{ 480 Type: "object", 481 }, 482 }, 483 }, 484 }, 485 Names: apiextensionsv1.CustomResourceDefinitionNames{ 486 Plural: "foos", 487 }}, 488 }, 489 &v1beta1.CustomResourceDefinition{ 490 Spec: v1beta1.CustomResourceDefinitionSpec{ 491 Group: "qux.example.com", 492 Version: "v1beta1", 493 Names: v1beta1.CustomResourceDefinitionNames{ 494 Plural: "bazs", 495 }}, 496 }, 497 &v1beta1.CustomResourceDefinition{ 498 Spec: v1beta1.CustomResourceDefinitionSpec{ 499 Group: "crew.example.com", 500 Version: "v1beta1", 501 Names: v1beta1.CustomResourceDefinitionNames{ 502 Plural: "captains", 503 }}, 504 }, 505 &v1beta1.CustomResourceDefinition{ 506 Spec: v1beta1.CustomResourceDefinitionSpec{ 507 Group: "crew.example.com", 508 Version: "v1beta1", 509 Names: v1beta1.CustomResourceDefinitionNames{ 510 Plural: "firstmates", 511 }}, 512 }, 513 &v1beta1.CustomResourceDefinition{ 514 Spec: v1beta1.CustomResourceDefinitionSpec{ 515 Group: "crew.example.com", 516 Names: v1beta1.CustomResourceDefinitionNames{ 517 Plural: "drivers", 518 }, 519 Versions: []v1beta1.CustomResourceDefinitionVersion{ 520 { 521 Name: "v1", 522 Storage: true, 523 Served: true, 524 }, 525 { 526 Name: "v2", 527 Storage: false, 528 Served: true, 529 }, 530 }}, 531 }, 532 }, 533 CRDInstallOptions{MaxTime: 50 * time.Millisecond, PollInterval: 15 * time.Millisecond}, 534 ) 535 Expect(err).NotTo(HaveOccurred()) 536 537 close(done) 538 }, 5) 539 }) 540 541 It("should update CRDs if already present in the cluster", func(done Done) { 542 543 // Install only the CRDv1 multi-version example 544 crds, err = InstallCRDs(env.Config, CRDInstallOptions{ 545 Paths: []string{filepath.Join(".", "testdata")}, 546 }) 547 Expect(err).NotTo(HaveOccurred()) 548 549 // Expect to find the CRDs 550 551 crd := &v1beta1.CustomResourceDefinition{} 552 err = c.Get(context.TODO(), types.NamespacedName{Name: "drivers.crew.example.com"}, crd) 553 Expect(err).NotTo(HaveOccurred()) 554 Expect(crd.Spec.Names.Kind).To(Equal("Driver")) 555 Expect(len(crd.Spec.Versions)).To(BeEquivalentTo(2)) 556 557 // Store resource version for comparison later on 558 firstRV := crd.ResourceVersion 559 560 err = WaitForCRDs(env.Config, []runtime.Object{ 561 &v1beta1.CustomResourceDefinition{ 562 Spec: v1beta1.CustomResourceDefinitionSpec{ 563 Group: "crew.example.com", 564 Names: v1beta1.CustomResourceDefinitionNames{ 565 Plural: "drivers", 566 }, 567 Versions: []v1beta1.CustomResourceDefinitionVersion{ 568 { 569 Name: "v1", 570 Storage: true, 571 Served: true, 572 }, 573 { 574 Name: "v2", 575 Storage: false, 576 Served: true, 577 }, 578 }}, 579 }, 580 }, 581 CRDInstallOptions{MaxTime: 50 * time.Millisecond, PollInterval: 15 * time.Millisecond}, 582 ) 583 Expect(err).NotTo(HaveOccurred()) 584 585 // Add one more version and update 586 _, err = InstallCRDs(env.Config, CRDInstallOptions{ 587 Paths: []string{filepath.Join(".", "testdata", "crdv1_updated")}, 588 }) 589 Expect(err).NotTo(HaveOccurred()) 590 591 // Expect to find updated CRD 592 593 crd = &v1beta1.CustomResourceDefinition{} 594 err = c.Get(context.TODO(), types.NamespacedName{Name: "drivers.crew.example.com"}, crd) 595 Expect(err).NotTo(HaveOccurred()) 596 Expect(crd.Spec.Names.Kind).To(Equal("Driver")) 597 Expect(len(crd.Spec.Versions)).To(BeEquivalentTo(3)) 598 Expect(crd.ResourceVersion).NotTo(BeEquivalentTo(firstRV)) 599 600 err = WaitForCRDs(env.Config, []runtime.Object{ 601 &v1beta1.CustomResourceDefinition{ 602 Spec: v1beta1.CustomResourceDefinitionSpec{ 603 Group: "crew.example.com", 604 Names: v1beta1.CustomResourceDefinitionNames{ 605 Plural: "drivers", 606 }, 607 Versions: []v1beta1.CustomResourceDefinitionVersion{ 608 { 609 Name: "v1", 610 Storage: true, 611 Served: true, 612 }, 613 { 614 Name: "v2", 615 Storage: false, 616 Served: true, 617 }, 618 { 619 Name: "v3", 620 Storage: false, 621 Served: true, 622 }, 623 }}, 624 }, 625 }, 626 CRDInstallOptions{MaxTime: 50 * time.Millisecond, PollInterval: 15 * time.Millisecond}, 627 ) 628 Expect(err).NotTo(HaveOccurred()) 629 630 close(done) 631 }, 5) 632 633 Describe("UninstallCRDs", func() { 634 It("should uninstall the CRDs from the cluster", func(done Done) { 635 636 crds, err = InstallCRDs(env.Config, CRDInstallOptions{ 637 Paths: []string{validDirectory}, 638 }) 639 Expect(err).NotTo(HaveOccurred()) 640 641 // Expect to find the CRDs 642 643 crdv1 := &apiextensionsv1.CustomResourceDefinition{} 644 err = c.Get(context.TODO(), types.NamespacedName{Name: "foos.bar.example.com"}, crdv1) 645 Expect(err).NotTo(HaveOccurred()) 646 Expect(crdv1.Spec.Names.Kind).To(Equal("Foo")) 647 648 crd := &v1beta1.CustomResourceDefinition{} 649 err = c.Get(context.TODO(), types.NamespacedName{Name: "bazs.qux.example.com"}, crd) 650 Expect(err).NotTo(HaveOccurred()) 651 Expect(crd.Spec.Names.Kind).To(Equal("Baz")) 652 653 crd = &v1beta1.CustomResourceDefinition{} 654 err = c.Get(context.TODO(), types.NamespacedName{Name: "captains.crew.example.com"}, crd) 655 Expect(err).NotTo(HaveOccurred()) 656 Expect(crd.Spec.Names.Kind).To(Equal("Captain")) 657 658 crd = &v1beta1.CustomResourceDefinition{} 659 err = c.Get(context.TODO(), types.NamespacedName{Name: "firstmates.crew.example.com"}, crd) 660 Expect(err).NotTo(HaveOccurred()) 661 Expect(crd.Spec.Names.Kind).To(Equal("FirstMate")) 662 663 crd = &v1beta1.CustomResourceDefinition{} 664 err = c.Get(context.TODO(), types.NamespacedName{Name: "drivers.crew.example.com"}, crd) 665 Expect(err).NotTo(HaveOccurred()) 666 Expect(crd.Spec.Names.Kind).To(Equal("Driver")) 667 668 err = WaitForCRDs(env.Config, []runtime.Object{ 669 &apiextensionsv1.CustomResourceDefinition{ 670 Spec: apiextensionsv1.CustomResourceDefinitionSpec{ 671 Group: "bar.example.com", 672 Versions: []apiextensionsv1.CustomResourceDefinitionVersion{ 673 { 674 Name: "v1", 675 Storage: true, 676 Served: true, 677 Schema: &apiextensionsv1.CustomResourceValidation{ 678 OpenAPIV3Schema: &apiextensionsv1.JSONSchemaProps{ 679 Type: "object", 680 }, 681 }, 682 }, 683 }, 684 Names: apiextensionsv1.CustomResourceDefinitionNames{ 685 Plural: "foos", 686 }}, 687 }, 688 &v1beta1.CustomResourceDefinition{ 689 Spec: v1beta1.CustomResourceDefinitionSpec{ 690 Group: "qux.example.com", 691 Version: "v1beta1", 692 Names: v1beta1.CustomResourceDefinitionNames{ 693 Plural: "bazs", 694 }}, 695 }, 696 &v1beta1.CustomResourceDefinition{ 697 Spec: v1beta1.CustomResourceDefinitionSpec{ 698 Group: "crew.example.com", 699 Version: "v1beta1", 700 Names: v1beta1.CustomResourceDefinitionNames{ 701 Plural: "captains", 702 }}, 703 }, 704 &v1beta1.CustomResourceDefinition{ 705 Spec: v1beta1.CustomResourceDefinitionSpec{ 706 Group: "crew.example.com", 707 Version: "v1beta1", 708 Names: v1beta1.CustomResourceDefinitionNames{ 709 Plural: "firstmates", 710 }}, 711 }, 712 &v1beta1.CustomResourceDefinition{ 713 Spec: v1beta1.CustomResourceDefinitionSpec{ 714 Group: "crew.example.com", 715 Names: v1beta1.CustomResourceDefinitionNames{ 716 Plural: "drivers", 717 }, 718 Versions: []v1beta1.CustomResourceDefinitionVersion{ 719 { 720 Name: "v1", 721 Storage: true, 722 Served: true, 723 }, 724 { 725 Name: "v2", 726 Storage: false, 727 Served: true, 728 }, 729 }}, 730 }, 731 }, 732 CRDInstallOptions{MaxTime: 50 * time.Millisecond, PollInterval: 15 * time.Millisecond}, 733 ) 734 Expect(err).NotTo(HaveOccurred()) 735 736 err = UninstallCRDs(env.Config, CRDInstallOptions{ 737 Paths: []string{validDirectory}, 738 }) 739 Expect(err).NotTo(HaveOccurred()) 740 741 // Expect to NOT find the CRDs 742 743 v1crds := []string{ 744 "foos.bar.example.com", 745 } 746 v1placeholder := &apiextensionsv1.CustomResourceDefinition{} 747 Eventually(func() bool { 748 for _, crd := range v1crds { 749 err = c.Get(context.TODO(), types.NamespacedName{Name: crd}, v1placeholder) 750 notFound := err != nil && apierrors.IsNotFound(err) 751 if !notFound { 752 return false 753 } 754 } 755 return true 756 }, 20).Should(BeTrue()) 757 758 v1beta1crds := []string{ 759 "bazs.qux.example.com", 760 "captains.crew.example.com", 761 "firstmates.crew.example.com", 762 "drivers.crew.example.com", 763 } 764 v1beta1placeholder := &v1beta1.CustomResourceDefinition{} 765 Eventually(func() bool { 766 for _, crd := range v1beta1crds { 767 err = c.Get(context.TODO(), types.NamespacedName{Name: crd}, v1beta1placeholder) 768 notFound := err != nil && apierrors.IsNotFound(err) 769 if !notFound { 770 return false 771 } 772 } 773 return true 774 }, 20).Should(BeTrue()) 775 776 close(done) 777 }, 30) 778 }) 779 780 Describe("Start", func() { 781 It("should raise an error on invalid dir when flag is enabled", func(done Done) { 782 env := &Environment{ErrorIfCRDPathMissing: true, CRDDirectoryPaths: []string{invalidDirectory}} 783 _, err := env.Start() 784 Expect(err).To(HaveOccurred()) 785 Expect(env.Stop()).To(Succeed()) 786 close(done) 787 }, 30) 788 789 It("should not raise an error on invalid dir when flag is disabled", func(done Done) { 790 env := &Environment{ErrorIfCRDPathMissing: false, CRDDirectoryPaths: []string{invalidDirectory}} 791 _, err := env.Start() 792 Expect(err).NotTo(HaveOccurred()) 793 Expect(env.Stop()).To(Succeed()) 794 close(done) 795 }, 30) 796 }) 797}) 798