Skip to content

Commit 0d78900

Browse files
authored
Merge pull request kubernetes-sigs#696 from pires/pires/dont_error_if_crd_present
✨ update CRD if already present
2 parents a7c8a93 + 5fc0586 commit 0d78900

File tree

4 files changed

+1017
-2
lines changed

4 files changed

+1017
-2
lines changed

pkg/envtest/crd.go

+13-2
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,19 @@ func CreateCRDs(config *rest.Config, crds []*apiextensionsv1beta1.CustomResource
221221
// Create each CRD
222222
for _, crd := range crds {
223223
log.V(1).Info("installing CRD", "crd", crd.Name)
224-
if _, err := cs.ApiextensionsV1beta1().CustomResourceDefinitions().Create(crd); err != nil {
225-
return err
224+
if existingCrd, err := cs.ApiextensionsV1beta1().CustomResourceDefinitions().Get(crd.Name, metav1.GetOptions{}); err != nil {
225+
if !apierrors.IsNotFound(err) {
226+
return err
227+
}
228+
if _, err := cs.ApiextensionsV1beta1().CustomResourceDefinitions().Create(crd); err != nil {
229+
return err
230+
}
231+
} else {
232+
log.V(1).Info("CRD already exists, updating", "crd", crd.Name)
233+
crd.ResourceVersion = existingCrd.ResourceVersion
234+
if _, err := cs.ApiextensionsV1beta1().CustomResourceDefinitions().Update(crd); err != nil {
235+
return err
236+
}
226237
}
227238
}
228239
return nil

pkg/envtest/envtest_test.go

+277
Original file line numberDiff line numberDiff line change
@@ -298,8 +298,285 @@ var _ = Describe("Test", func() {
298298

299299
close(done)
300300
}, 5)
301+
302+
It("should reinstall the CRDs if already present in the cluster", func(done Done) {
303+
304+
crds, err = InstallCRDs(env.Config, CRDInstallOptions{
305+
Paths: []string{filepath.Join(".", "testdata")},
306+
})
307+
Expect(err).NotTo(HaveOccurred())
308+
309+
// Expect to find the CRDs
310+
311+
crd := &v1beta1.CustomResourceDefinition{}
312+
err = c.Get(context.TODO(), types.NamespacedName{Name: "foos.bar.example.com"}, crd)
313+
Expect(err).NotTo(HaveOccurred())
314+
Expect(crd.Spec.Names.Kind).To(Equal("Foo"))
315+
316+
crd = &v1beta1.CustomResourceDefinition{}
317+
err = c.Get(context.TODO(), types.NamespacedName{Name: "bazs.qux.example.com"}, crd)
318+
Expect(err).NotTo(HaveOccurred())
319+
Expect(crd.Spec.Names.Kind).To(Equal("Baz"))
320+
321+
crd = &v1beta1.CustomResourceDefinition{}
322+
err = c.Get(context.TODO(), types.NamespacedName{Name: "captains.crew.example.com"}, crd)
323+
Expect(err).NotTo(HaveOccurred())
324+
Expect(crd.Spec.Names.Kind).To(Equal("Captain"))
325+
326+
crd = &v1beta1.CustomResourceDefinition{}
327+
err = c.Get(context.TODO(), types.NamespacedName{Name: "firstmates.crew.example.com"}, crd)
328+
Expect(err).NotTo(HaveOccurred())
329+
Expect(crd.Spec.Names.Kind).To(Equal("FirstMate"))
330+
331+
crd = &v1beta1.CustomResourceDefinition{}
332+
err = c.Get(context.TODO(), types.NamespacedName{Name: "drivers.crew.example.com"}, crd)
333+
Expect(err).NotTo(HaveOccurred())
334+
Expect(crd.Spec.Names.Kind).To(Equal("Driver"))
335+
336+
err = WaitForCRDs(env.Config, []*v1beta1.CustomResourceDefinition{
337+
{
338+
Spec: v1beta1.CustomResourceDefinitionSpec{
339+
Group: "qux.example.com",
340+
Version: "v1beta1",
341+
Names: v1beta1.CustomResourceDefinitionNames{
342+
Plural: "bazs",
343+
}},
344+
},
345+
{
346+
Spec: v1beta1.CustomResourceDefinitionSpec{
347+
Group: "bar.example.com",
348+
Version: "v1beta1",
349+
Names: v1beta1.CustomResourceDefinitionNames{
350+
Plural: "foos",
351+
}},
352+
},
353+
{
354+
Spec: v1beta1.CustomResourceDefinitionSpec{
355+
Group: "crew.example.com",
356+
Version: "v1beta1",
357+
Names: v1beta1.CustomResourceDefinitionNames{
358+
Plural: "captains",
359+
}},
360+
},
361+
{
362+
Spec: v1beta1.CustomResourceDefinitionSpec{
363+
Group: "crew.example.com",
364+
Version: "v1beta1",
365+
Names: v1beta1.CustomResourceDefinitionNames{
366+
Plural: "firstmates",
367+
}},
368+
},
369+
{
370+
Spec: v1beta1.CustomResourceDefinitionSpec{
371+
Group: "crew.example.com",
372+
Names: v1beta1.CustomResourceDefinitionNames{
373+
Plural: "drivers",
374+
},
375+
Versions: []v1beta1.CustomResourceDefinitionVersion{
376+
{
377+
Name: "v1",
378+
Storage: true,
379+
Served: true,
380+
},
381+
{
382+
Name: "v2",
383+
Storage: false,
384+
Served: true,
385+
},
386+
}},
387+
},
388+
},
389+
CRDInstallOptions{MaxTime: 50 * time.Millisecond, PollInterval: 15 * time.Millisecond},
390+
)
391+
Expect(err).NotTo(HaveOccurred())
392+
393+
// Try to re-install the CRDs
394+
395+
crds, err = InstallCRDs(env.Config, CRDInstallOptions{
396+
Paths: []string{filepath.Join(".", "testdata")},
397+
})
398+
Expect(err).NotTo(HaveOccurred())
399+
400+
// Expect to find the CRDs
401+
402+
crd = &v1beta1.CustomResourceDefinition{}
403+
err = c.Get(context.TODO(), types.NamespacedName{Name: "foos.bar.example.com"}, crd)
404+
Expect(err).NotTo(HaveOccurred())
405+
Expect(crd.Spec.Names.Kind).To(Equal("Foo"))
406+
407+
crd = &v1beta1.CustomResourceDefinition{}
408+
err = c.Get(context.TODO(), types.NamespacedName{Name: "bazs.qux.example.com"}, crd)
409+
Expect(err).NotTo(HaveOccurred())
410+
Expect(crd.Spec.Names.Kind).To(Equal("Baz"))
411+
412+
crd = &v1beta1.CustomResourceDefinition{}
413+
err = c.Get(context.TODO(), types.NamespacedName{Name: "captains.crew.example.com"}, crd)
414+
Expect(err).NotTo(HaveOccurred())
415+
Expect(crd.Spec.Names.Kind).To(Equal("Captain"))
416+
417+
crd = &v1beta1.CustomResourceDefinition{}
418+
err = c.Get(context.TODO(), types.NamespacedName{Name: "firstmates.crew.example.com"}, crd)
419+
Expect(err).NotTo(HaveOccurred())
420+
Expect(crd.Spec.Names.Kind).To(Equal("FirstMate"))
421+
422+
crd = &v1beta1.CustomResourceDefinition{}
423+
err = c.Get(context.TODO(), types.NamespacedName{Name: "drivers.crew.example.com"}, crd)
424+
Expect(err).NotTo(HaveOccurred())
425+
Expect(crd.Spec.Names.Kind).To(Equal("Driver"))
426+
427+
err = WaitForCRDs(env.Config, []*v1beta1.CustomResourceDefinition{
428+
{
429+
Spec: v1beta1.CustomResourceDefinitionSpec{
430+
Group: "qux.example.com",
431+
Version: "v1beta1",
432+
Names: v1beta1.CustomResourceDefinitionNames{
433+
Plural: "bazs",
434+
}},
435+
},
436+
{
437+
Spec: v1beta1.CustomResourceDefinitionSpec{
438+
Group: "bar.example.com",
439+
Version: "v1beta1",
440+
Names: v1beta1.CustomResourceDefinitionNames{
441+
Plural: "foos",
442+
}},
443+
},
444+
{
445+
Spec: v1beta1.CustomResourceDefinitionSpec{
446+
Group: "crew.example.com",
447+
Version: "v1beta1",
448+
Names: v1beta1.CustomResourceDefinitionNames{
449+
Plural: "captains",
450+
}},
451+
},
452+
{
453+
Spec: v1beta1.CustomResourceDefinitionSpec{
454+
Group: "crew.example.com",
455+
Version: "v1beta1",
456+
Names: v1beta1.CustomResourceDefinitionNames{
457+
Plural: "firstmates",
458+
}},
459+
},
460+
{
461+
Spec: v1beta1.CustomResourceDefinitionSpec{
462+
Group: "crew.example.com",
463+
Names: v1beta1.CustomResourceDefinitionNames{
464+
Plural: "drivers",
465+
},
466+
Versions: []v1beta1.CustomResourceDefinitionVersion{
467+
{
468+
Name: "v1",
469+
Storage: true,
470+
Served: true,
471+
},
472+
{
473+
Name: "v2",
474+
Storage: false,
475+
Served: true,
476+
},
477+
}},
478+
},
479+
},
480+
CRDInstallOptions{MaxTime: 50 * time.Millisecond, PollInterval: 15 * time.Millisecond},
481+
)
482+
Expect(err).NotTo(HaveOccurred())
483+
484+
close(done)
485+
}, 5)
301486
})
302487

488+
It("should update CRDs if already present in the cluster", func(done Done) {
489+
490+
// Install only the CRDv1 multi-version example
491+
crds, err = InstallCRDs(env.Config, CRDInstallOptions{
492+
Paths: []string{filepath.Join(".", "testdata")},
493+
})
494+
Expect(err).NotTo(HaveOccurred())
495+
496+
// Expect to find the CRDs
497+
498+
crd := &v1beta1.CustomResourceDefinition{}
499+
err = c.Get(context.TODO(), types.NamespacedName{Name: "drivers.crew.example.com"}, crd)
500+
Expect(err).NotTo(HaveOccurred())
501+
Expect(crd.Spec.Names.Kind).To(Equal("Driver"))
502+
Expect(len(crd.Spec.Versions)).To(BeEquivalentTo(2))
503+
504+
// Store resource version for comparison later on
505+
firstRV := crd.ResourceVersion
506+
507+
err = WaitForCRDs(env.Config, []*v1beta1.CustomResourceDefinition{
508+
{
509+
Spec: v1beta1.CustomResourceDefinitionSpec{
510+
Group: "crew.example.com",
511+
Names: v1beta1.CustomResourceDefinitionNames{
512+
Plural: "drivers",
513+
},
514+
Versions: []v1beta1.CustomResourceDefinitionVersion{
515+
{
516+
Name: "v1",
517+
Storage: true,
518+
Served: true,
519+
},
520+
{
521+
Name: "v2",
522+
Storage: false,
523+
Served: true,
524+
},
525+
}},
526+
},
527+
},
528+
CRDInstallOptions{MaxTime: 50 * time.Millisecond, PollInterval: 15 * time.Millisecond},
529+
)
530+
Expect(err).NotTo(HaveOccurred())
531+
532+
// Add one more version and update
533+
_, err = InstallCRDs(env.Config, CRDInstallOptions{
534+
Paths: []string{filepath.Join(".", "testdata", "crdv1_updated")},
535+
})
536+
Expect(err).NotTo(HaveOccurred())
537+
538+
// Expect to find updated CRD
539+
540+
crd = &v1beta1.CustomResourceDefinition{}
541+
err = c.Get(context.TODO(), types.NamespacedName{Name: "drivers.crew.example.com"}, crd)
542+
Expect(err).NotTo(HaveOccurred())
543+
Expect(crd.Spec.Names.Kind).To(Equal("Driver"))
544+
Expect(len(crd.Spec.Versions)).To(BeEquivalentTo(3))
545+
Expect(crd.ResourceVersion).NotTo(BeEquivalentTo(firstRV))
546+
547+
err = WaitForCRDs(env.Config, []*v1beta1.CustomResourceDefinition{
548+
{
549+
Spec: v1beta1.CustomResourceDefinitionSpec{
550+
Group: "crew.example.com",
551+
Names: v1beta1.CustomResourceDefinitionNames{
552+
Plural: "drivers",
553+
},
554+
Versions: []v1beta1.CustomResourceDefinitionVersion{
555+
{
556+
Name: "v1",
557+
Storage: true,
558+
Served: true,
559+
},
560+
{
561+
Name: "v2",
562+
Storage: false,
563+
Served: true,
564+
},
565+
{
566+
Name: "v3",
567+
Storage: false,
568+
Served: true,
569+
},
570+
}},
571+
},
572+
},
573+
CRDInstallOptions{MaxTime: 50 * time.Millisecond, PollInterval: 15 * time.Millisecond},
574+
)
575+
Expect(err).NotTo(HaveOccurred())
576+
577+
close(done)
578+
}, 5)
579+
303580
Describe("UninstallCRDs", func() {
304581
It("should uninstall the CRDs from the cluster", func(done Done) {
305582

0 commit comments

Comments
 (0)