diff --git a/controllers/namespace_controller_test.go b/controllers/namespace_controller_test.go index 3e8f849..22d9f40 100644 --- a/controllers/namespace_controller_test.go +++ b/controllers/namespace_controller_test.go @@ -2,7 +2,6 @@ package controllers import ( "context" - "errors" "time" accuratev2alpha1 "github.com/cybozu-go/accurate/api/accurate/v2alpha1" @@ -17,6 +16,7 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/envtest/komega" "sigs.k8s.io/controller-runtime/pkg/metrics/server" ) @@ -103,8 +103,7 @@ var _ = Describe("Namespace controller", func() { "memo": "memo", "team": "cat", } - err := k8sClient.Create(ctx, tmpl) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, tmpl)).To(Succeed()) role1 := roleRes.DeepCopy() role1.SetNamespace("tmpl") @@ -116,8 +115,7 @@ var _ = Describe("Namespace controller", func() { "verbs": []interface{}{"get", "watch", "list"}, }, } - err = k8sClient.Create(ctx, role1) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, role1)).To(Succeed()) role2 := roleRes.DeepCopy() role2.SetNamespace("tmpl") @@ -130,8 +128,7 @@ var _ = Describe("Namespace controller", func() { "verbs": []interface{}{"get", "watch", "list"}, }, } - err = k8sClient.Create(ctx, role2) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, role2)).To(Succeed()) secret := secretRes.DeepCopy() secret.SetNamespace("tmpl") @@ -140,13 +137,11 @@ var _ = Describe("Namespace controller", func() { "foo": "MjAyMC0wOS0xM1QwNDozOToxMFo=", } secret.SetAnnotations(map[string]string{constants.AnnPropagate: constants.PropagateUpdate}) - err = k8sClient.Create(ctx, secret) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, secret)).To(Succeed()) ns1 := &corev1.Namespace{} ns1.Name = "ns1" - err = k8sClient.Create(ctx, ns1) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, ns1)).To(Succeed()) secret2 := secretRes.DeepCopy() secret2.SetNamespace("ns1") @@ -155,72 +150,56 @@ var _ = Describe("Namespace controller", func() { "bar": "MjAyMC0wOS0xM1QwNDozOToxMFo=", } secret2.SetAnnotations(map[string]string{constants.AnnPropagate: constants.PropagateUpdate}) - err = k8sClient.Create(ctx, secret2) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, secret2)).To(Succeed()) time.Sleep(100 * time.Millisecond) By("setting the template namespace") - ns1.Labels = map[string]string{constants.LabelTemplate: "tmpl"} - err = k8sClient.Update(ctx, ns1) - Expect(err).NotTo(HaveOccurred()) + Expect(komega.Update(ns1, func() { + ns1.Labels = map[string]string{constants.LabelTemplate: "tmpl"} + })()).To(Succeed()) - Eventually(func() string { - ns1 = &corev1.Namespace{} - if err := k8sClient.Get(ctx, client.ObjectKey{Name: "ns1"}, ns1); err != nil { - return "" - } - return ns1.Labels["team"] - }).Should(Equal("neco")) + Eventually(komega.Object(ns1)).Should(HaveField("Labels", HaveKeyWithValue("team", "neco"))) Expect(ns1.Labels).To(HaveKeyWithValue("foo.bar/baz", "baz")) Expect(ns1.Labels).NotTo(HaveKey("memo")) Expect(ns1.Annotations).To(HaveKeyWithValue("foo.bar/zot", "zot")) Expect(ns1.Annotations).To(HaveKeyWithValue("memo", "memo")) Expect(ns1.Annotations).NotTo(HaveKey("team")) - var pRole *rbacv1.Role - Eventually(func() error { - pRole = &rbacv1.Role{} - return k8sClient.Get(ctx, client.ObjectKey{Namespace: "ns1", Name: "role2"}, pRole) - }).Should(Succeed()) + pRole := &rbacv1.Role{} + pRole.Name = "role2" + pRole.Namespace = ns1.Name + Eventually(komega.Get(pRole)).Should(Succeed()) Expect(pRole.Labels).To(HaveKeyWithValue(constants.LabelCreatedBy, constants.CreatedBy)) Expect(pRole.Annotations).To(HaveKeyWithValue(constants.AnnFrom, "tmpl")) Expect(pRole.Annotations).To(HaveKeyWithValue(constants.AnnPropagate, constants.PropagateCreate)) Expect(pRole.Rules).To(HaveLen(1)) - var pSecret *corev1.Secret - Eventually(func() error { - pSecret = &corev1.Secret{} - return k8sClient.Get(ctx, client.ObjectKey{Namespace: "ns1", Name: "foo"}, pSecret) - }).Should(Succeed()) + pSecret := &corev1.Secret{} + pSecret.Name = "foo" + pSecret.Namespace = ns1.Name + Eventually(komega.Get(pSecret)).Should(Succeed()) Expect(pSecret.Labels).To(HaveKeyWithValue(constants.LabelCreatedBy, constants.CreatedBy)) Expect(pSecret.Annotations).To(HaveKeyWithValue(constants.AnnFrom, "tmpl")) Expect(pSecret.Annotations).To(HaveKeyWithValue(constants.AnnPropagate, constants.PropagateUpdate)) Expect(pSecret.Data).To(HaveKey("foo")) pRole2 := &rbacv1.Role{} - err = k8sClient.Get(ctx, client.ObjectKey{Namespace: "ns1", Name: "role1"}, pRole2) - Expect(apierrors.IsNotFound(err)).To(BeTrue()) + pRole2.Name = "role1" + pRole2.Namespace = ns1.Name + Expect(komega.Get(pRole2)()).To(WithTransform(apierrors.IsNotFound, BeTrue())) pSecret2 := &corev1.Secret{} - err = k8sClient.Get(ctx, client.ObjectKey{Namespace: "ns1", Name: "bar"}, pSecret2) - Expect(err).NotTo(HaveOccurred()) + pSecret2.Name = "bar" + pSecret2.Namespace = ns1.Name + Expect(komega.Get(pSecret2)()).To(Succeed()) By("changing a label of template namespace") - tmpl = &corev1.Namespace{} - err = k8sClient.Get(ctx, client.ObjectKey{Name: "tmpl"}, tmpl) - Expect(err).NotTo(HaveOccurred()) - tmpl.Labels["foo.bar/baz"] = "123" - err = k8sClient.Update(ctx, tmpl) - Expect(err).NotTo(HaveOccurred()) + Expect(komega.Update(tmpl, func() { + tmpl.Labels["foo.bar/baz"] = "123" + })()).To(Succeed()) - Eventually(func() string { - ns1 = &corev1.Namespace{} - if err := k8sClient.Get(ctx, client.ObjectKey{Name: "ns1"}, ns1); err != nil { - return "" - } - return ns1.Labels["foo.bar/baz"] - }).Should(Equal("123")) + Eventually(komega.Object(ns1)).Should(HaveField("Labels", HaveKeyWithValue("foo.bar/baz", "123"))) tmpl2 := &corev1.Namespace{} tmpl2.Name = "tmpl2" @@ -228,55 +207,35 @@ var _ = Describe("Namespace controller", func() { constants.LabelType: constants.NSTypeTemplate, "team": "maneki", } - err = k8sClient.Create(ctx, tmpl2) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, tmpl2)).To(Succeed()) sec2 := &corev1.Secret{} - sec2.Namespace = "tmpl2" + sec2.Namespace = tmpl2.Name sec2.Name = "sec2" sec2.Annotations = map[string]string{constants.AnnPropagate: constants.PropagateUpdate} sec2.Data = map[string][]byte{"foo": []byte("barbar")} - err = k8sClient.Create(ctx, sec2) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, sec2)).To(Succeed()) By("changing the template namespace to tmpl2") - ns1.Labels[constants.LabelTemplate] = "tmpl2" - err = k8sClient.Update(ctx, ns1) - Expect(err).NotTo(HaveOccurred()) + Expect(komega.Update(ns1, func() { + ns1.Labels[constants.LabelTemplate] = "tmpl2" + })()).To(Succeed()) - Eventually(func() bool { - secret := &corev1.Secret{} - err := k8sClient.Get(ctx, client.ObjectKey{Namespace: "ns1", Name: "foo"}, secret) - return apierrors.IsNotFound(err) - }).Should(BeTrue()) - - Eventually(func() error { - secret := &corev1.Secret{} - return k8sClient.Get(ctx, client.ObjectKey{Namespace: "ns1", Name: "sec2"}, secret) - }).Should(Succeed()) - - Eventually(func() string { - ns1 = &corev1.Namespace{} - if err := k8sClient.Get(ctx, client.ObjectKey{Name: "ns1"}, ns1); err != nil { - return "" - } - return ns1.Labels["team"] - }).Should(Equal("maneki")) + Eventually(komega.Get(pSecret)).Should(WithTransform(apierrors.IsNotFound, BeTrue())) - By("unsetting the template") - ns1 = &corev1.Namespace{} - err = k8sClient.Get(ctx, client.ObjectKey{Name: "ns1"}, ns1) - Expect(err).NotTo(HaveOccurred()) + pSec2 := &corev1.Secret{} + pSec2.Name = "sec2" + pSec2.Namespace = ns1.Name + Eventually(komega.Get(pSec2)).Should(Succeed()) - delete(ns1.Labels, constants.LabelTemplate) - err = k8sClient.Update(ctx, ns1) - Expect(err).NotTo(HaveOccurred()) + Eventually(komega.Object(ns1)).Should(HaveField("Labels", HaveKeyWithValue("team", "maneki"))) + + By("unsetting the template") + Expect(komega.Update(ns1, func() { + delete(ns1.Labels, constants.LabelTemplate) + })()).To(Succeed()) - Eventually(func() bool { - secret := &corev1.Secret{} - err := k8sClient.Get(ctx, client.ObjectKey{Namespace: "ns1", Name: "sec2"}, secret) - return apierrors.IsNotFound(err) - }).Should(BeTrue()) + Eventually(komega.Get(pSec2)).Should(WithTransform(apierrors.IsNotFound, BeTrue())) }) It("should handle propagation between template namespaces", func() { @@ -286,8 +245,7 @@ var _ = Describe("Namespace controller", func() { constants.LabelType: constants.NSTypeTemplate, "team": "neco", } - err := k8sClient.Create(ctx, tmpl1) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, tmpl1)).To(Succeed()) tmpl2 := &corev1.Namespace{} tmpl2.Name = "tree-tmpl-2" @@ -296,47 +254,30 @@ var _ = Describe("Namespace controller", func() { constants.LabelTemplate: "tree-tmpl-1", } tmpl2.Annotations = map[string]string{"memo": "mome"} - err = k8sClient.Create(ctx, tmpl2) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, tmpl2)).To(Succeed()) instance := &corev1.Namespace{} instance.Name = "tree-instance" instance.Labels = map[string]string{ constants.LabelTemplate: "tree-tmpl-2", } - err = k8sClient.Create(ctx, instance) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, instance)).To(Succeed()) - Eventually(func() string { - instance = &corev1.Namespace{} - if err := k8sClient.Get(ctx, client.ObjectKey{Name: "tree-instance"}, instance); err != nil { - return "" - } - return instance.Labels["team"] + instance.Annotations["memo"] - }).Should(Equal("necomome")) + Eventually(komega.Object(instance)).Should(And( + HaveField("Labels", HaveKeyWithValue("team", "neco")), + HaveField("Annotations", HaveKeyWithValue("memo", "mome")), + )) - tmpl2 = &corev1.Namespace{} - err = k8sClient.Get(ctx, client.ObjectKey{Name: "tree-tmpl-2"}, tmpl2) - Expect(err).NotTo(HaveOccurred()) - tmpl2.Labels["team"] = "hoge" - tmpl2.Annotations["memo"] = "test" - err = k8sClient.Update(ctx, tmpl2) - Expect(err).NotTo(HaveOccurred()) + Expect(komega.Update(tmpl2, func() { + tmpl2.Labels["team"] = "hoge" + tmpl2.Annotations["memo"] = "test" + })()).To(Succeed()) - Consistently(func() string { - instance = &corev1.Namespace{} - if err := k8sClient.Get(ctx, client.ObjectKey{Name: "tree-instance"}, instance); err != nil { - return "" - } - return instance.Labels["team"] - }).Should(Equal("neco")) + Consistently(komega.Object(instance)).Should(HaveField("Labels", HaveKeyWithValue("team", "neco"))) Expect(instance.Annotations["memo"]).Should(Equal("test")) - tmpl2 = &corev1.Namespace{} - err = k8sClient.Get(ctx, client.ObjectKey{Name: "tree-tmpl-2"}, tmpl2) - Expect(err).NotTo(HaveOccurred()) - Expect(tmpl2.Labels["team"]).Should(Equal("neco")) + Expect(komega.Object(tmpl2)()).To(HaveField("Labels", HaveKeyWithValue("team", "neco"))) }) It("should not delete resources in an independent namespace", func() { @@ -346,26 +287,20 @@ var _ = Describe("Namespace controller", func() { secret.Annotations = map[string]string{constants.AnnPropagate: constants.PropagateUpdate} secret.Data = map[string][]byte{"foo": []byte("bar")} - err := k8sClient.Create(ctx, secret) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, secret)).To(Succeed()) time.Sleep(100 * time.Millisecond) ns := &corev1.Namespace{} - err = k8sClient.Get(ctx, client.ObjectKey{Name: "default"}, ns) - Expect(err).NotTo(HaveOccurred()) - - if ns.Labels == nil { - ns.Labels = make(map[string]string) - } - ns.Labels["accurate-test"] = "test" - err = k8sClient.Update(ctx, ns) - Expect(err).NotTo(HaveOccurred()) + ns.Name = "default" + Expect(komega.Update(ns, func() { + if ns.Labels == nil { + ns.Labels = make(map[string]string) + } + ns.Labels["accurate-test"] = "test" + })()).To(Succeed()) - Consistently(func() error { - s := &corev1.Secret{} - return k8sClient.Get(ctx, client.ObjectKey{Namespace: "default", Name: "independent"}, s) - }, 1, 0.1).Should(Succeed()) + Consistently(komega.Get(secret), 1, 0.1).Should(Succeed()) }) It("should implement a sub namespace correctly", func() { @@ -383,46 +318,35 @@ var _ = Describe("Namespace controller", func() { "baz.glob/c": "delete-me", "do.not.match/glob.patten": "glob", } - err := k8sClient.Create(ctx, root) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, root)).To(Succeed()) sec1 := &corev1.Secret{} sec1.Namespace = "root" sec1.Name = "sec1" sec1.Data = map[string][]byte{"foo": []byte("bar")} - err = k8sClient.Create(ctx, sec1) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, sec1)).To(Succeed()) sec2 := &corev1.Secret{} sec2.Namespace = "root" sec2.Name = "sec2" sec2.Annotations = map[string]string{constants.AnnPropagate: constants.PropagateCreate} sec2.Data = map[string][]byte{"foo": []byte("bar")} - err = k8sClient.Create(ctx, sec2) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, sec2)).To(Succeed()) sec3 := &corev1.Secret{} sec3.Namespace = "root" sec3.Name = "sec3" sec3.Annotations = map[string]string{constants.AnnPropagate: constants.PropagateUpdate} sec3.Data = map[string][]byte{"foo": []byte("bar")} - err = k8sClient.Create(ctx, sec3) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, sec3)).To(Succeed()) By("creating a sub namespace") sub1 := &corev1.Namespace{} sub1.Name = "sub1" sub1.Labels = map[string]string{constants.LabelParent: "root"} - err = k8sClient.Create(ctx, sub1) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, sub1)).To(Succeed()) - Eventually(func() string { - sub1 = &corev1.Namespace{} - if err := k8sClient.Get(ctx, client.ObjectKey{Name: "sub1"}, sub1); err != nil { - return "" - } - return sub1.Labels["team"] - }).Should(Equal("neco")) + Eventually(komega.Object(sub1)).Should(HaveField("Labels", HaveKeyWithValue("team", "neco"))) Expect(sub1.Labels).Should(HaveKeyWithValue("foo.glob/a", "glob")) Expect(sub1.Labels).NotTo(HaveKey(constants.LabelType)) Expect(sub1.Labels).NotTo(HaveKey("do.not.match/glob/patten")) @@ -431,70 +355,47 @@ var _ = Describe("Namespace controller", func() { Expect(sub1.Annotations).NotTo(HaveKey("foo")) Expect(sub1.Annotations).NotTo(HaveKey("do.not.match/glob/patten")) - Eventually(func() error { - cSec2 := &corev1.Secret{} - return k8sClient.Get(ctx, client.ObjectKey{Namespace: "sub1", Name: "sec2"}, cSec2) - }).Should(Succeed()) - Eventually(func() error { - cSec3 := &corev1.Secret{} - return k8sClient.Get(ctx, client.ObjectKey{Namespace: "sub1", Name: "sec3"}, cSec3) - }).Should(Succeed()) + cSec2 := &corev1.Secret{} + cSec2.Name = "sec2" + cSec2.Namespace = sub1.Name + Eventually(komega.Get(cSec2)).Should(Succeed()) + cSec3 := &corev1.Secret{} + cSec3.Name = "sec3" + cSec3.Namespace = sub1.Name + Eventually(komega.Get(cSec3)).Should(Succeed()) By("creating a grandchild namespace") sub2 := &corev1.Namespace{} sub2.Name = "sub2" sub2.Labels = map[string]string{constants.LabelParent: "sub1"} - err = k8sClient.Create(ctx, sub2) - Expect(err).NotTo(HaveOccurred()) - - Eventually(func() string { - sub2 = &corev1.Namespace{} - if err := k8sClient.Get(ctx, client.ObjectKey{Name: "sub2"}, sub2); err != nil { - return "" - } - return sub2.Labels["team"] - }).Should(Equal("neco")) - Eventually(func() error { - cSec2 := &corev1.Secret{} - return k8sClient.Get(ctx, client.ObjectKey{Namespace: "sub2", Name: "sec2"}, cSec2) - }).Should(Succeed()) - Eventually(func() error { - cSec3 := &corev1.Secret{} - return k8sClient.Get(ctx, client.ObjectKey{Namespace: "sub2", Name: "sec3"}, cSec3) - }).Should(Succeed()) + Expect(k8sClient.Create(ctx, sub2)).To(Succeed()) + + Eventually(komega.Object(sub2)).Should(HaveField("Labels", HaveKeyWithValue("team", "neco"))) + gcSec2 := &corev1.Secret{} + gcSec2.Name = sec2.Name + gcSec2.Namespace = sub2.Name + Eventually(komega.Get(gcSec2)).Should(Succeed()) + gcSec3 := &corev1.Secret{} + gcSec3.Name = sec3.Name + gcSec3.Namespace = sub2.Name + Eventually(komega.Get(gcSec3)).Should(Succeed()) By("editing a label of root namespace") - root.Labels["team"] = "nuco" - err = k8sClient.Update(ctx, root) - Expect(err).NotTo(HaveOccurred()) + Expect(komega.Update(root, func() { + root.Labels["team"] = "nuco" + })()).To(Succeed()) - Eventually(func() string { - sub1 = &corev1.Namespace{} - if err := k8sClient.Get(ctx, client.ObjectKey{Name: "sub1"}, sub1); err != nil { - return "" - } - return sub1.Labels["team"] - }).Should(Equal("nuco")) - Eventually(func() string { - sub2 = &corev1.Namespace{} - if err := k8sClient.Get(ctx, client.ObjectKey{Name: "sub2"}, sub2); err != nil { - return "" - } - return sub2.Labels["team"] - }).Should(Equal("nuco")) + Eventually(komega.Object(sub1)).Should(HaveField("Labels", HaveKeyWithValue("team", "nuco"))) + Eventually(komega.Object(sub2)).Should(HaveField("Labels", HaveKeyWithValue("team", "nuco"))) By("deleting an annotation in root namespace") - delete(root.Labels, "baz.glob/c") - Eventually(func() error { - sub1 = &corev1.Namespace{} - if err := k8sClient.Get(ctx, client.ObjectKey{Name: "sub1"}, sub1); err != nil { - return err - } - if _, ok := sub1.Annotations["baz.glob/c"]; !ok { - return errors.New("annotation has been deleted") - } - return nil - }).Should(Succeed()) + Expect(komega.Update(root, func() { + delete(root.Labels, "baz.glob/c") + })()).To(Succeed()) + // Cleaning up obsolete labels/annotations from sub-namespaces is currently unsupported + // See https://github.com/cybozu-go/accurate/issues/98 + Consistently(komega.Object(sub1)).Should(HaveField("Annotations", HaveKey("baz.glob/c"))) + //Eventually(komega.Object(sub1)).Should(HaveField("Annotations", Not(HaveKey("baz.glob/c")))) By("changing the parent of sub2") root2 := &corev1.Namespace{} @@ -503,30 +404,17 @@ var _ = Describe("Namespace controller", func() { constants.LabelType: constants.NSTypeRoot, "foo.bar/baz": "baz", } - err = k8sClient.Create(ctx, root2) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, root2)).To(Succeed()) - sub2.Labels[constants.LabelParent] = "root2" - err = k8sClient.Update(ctx, sub2) - Expect(err).NotTo(HaveOccurred()) + Expect(komega.Update(sub2, func() { + sub2.Labels[constants.LabelParent] = "root2" + })()).To(Succeed()) - Eventually(func() string { - sub2 = &corev1.Namespace{} - if err := k8sClient.Get(ctx, client.ObjectKey{Name: "sub2"}, sub2); err != nil { - return "" - } - return sub2.Labels["foo.bar/baz"] - }).Should(Equal("baz")) + Eventually(komega.Object(sub2)).Should(HaveField("Labels", HaveKeyWithValue("foo.bar/baz", "baz"))) - Eventually(func() bool { - sec := &corev1.Secret{} - err := k8sClient.Get(ctx, client.ObjectKey{Namespace: "sub2", Name: "sec3"}, sec) - return apierrors.IsNotFound(err) - }).Should(BeTrue()) + Eventually(komega.Get(gcSec3)).Should(WithTransform(apierrors.IsNotFound, BeTrue())) - cSec2 := &corev1.Secret{} - err = k8sClient.Get(ctx, client.ObjectKey{Namespace: "sub2", Name: "sec2"}, cSec2) - Expect(err).NotTo(HaveOccurred()) + Expect(komega.Get(gcSec2)()).To(Succeed()) By("creating a SubNamespace for sub1 namespace") sn := &accuratev2alpha1.SubNamespace{} @@ -541,91 +429,37 @@ var _ = Describe("Namespace controller", func() { "empty": "true", } sn.Finalizers = []string{constants.Finalizer} - err = k8sClient.Create(ctx, sn) - Expect(err).NotTo(HaveOccurred()) - Eventually(func() error { - sub1 := &corev1.Namespace{} - err := k8sClient.Get(ctx, client.ObjectKey{Name: "sub1"}, sub1) - if err != nil { - return err - } - - if sub1.Labels["team"] != "neco" { - return errors.New("team label is not neco") - } - if _, ok := sub1.Labels["empty"]; ok { - return errors.New("empty label is propagated") - } - - if sub1.Annotations["memo"] != "neco" { - return errors.New("memo annotation is not neco") - } - if _, ok := sub1.Annotations["empty"]; ok { - return errors.New("empty annotation is propagated") - } - return nil - }).Should(Succeed()) + Expect(k8sClient.Create(ctx, sn)).To(Succeed()) + Eventually(komega.Object(sub1)).Should(And( + HaveField("Labels", HaveKeyWithValue("team", "neco")), + HaveField("Labels", Not(HaveKey("empty"))), + HaveField("Annotations", HaveKeyWithValue("memo", "neco")), + HaveField("Annotations", Not(HaveKey("empty"))), + )) By("returning the parent of sub2") - sub2.Labels[constants.LabelParent] = "sub1" - err = k8sClient.Update(ctx, sub2) - Expect(err).NotTo(HaveOccurred()) - Eventually(func() error { - sub2 := &corev1.Namespace{} - err := k8sClient.Get(ctx, client.ObjectKey{Name: "sub2"}, sub2) - if err != nil { - return err - } - - if sub2.Labels["team"] != "neco" { - return errors.New("team label is not neco") - } - if _, ok := sub2.Labels["empty"]; ok { - return errors.New("empty label is propagated") - } - - if sub2.Annotations["memo"] != "neco" { - return errors.New("memo annotation is not neco") - } - if _, ok := sub2.Annotations["empty"]; ok { - return errors.New("empty annotation is propagated") - } - return nil - }).Should(Succeed()) + Expect(komega.Update(sub2, func() { + sub2.Labels[constants.LabelParent] = "sub1" + })()).To(Succeed()) + Eventually(komega.Object(sub2)).Should(And( + HaveField("Labels", HaveKeyWithValue("team", "neco")), + HaveField("Labels", Not(HaveKey("empty"))), + HaveField("Annotations", HaveKeyWithValue("memo", "neco")), + HaveField("Annotations", Not(HaveKey("empty"))), + )) By("updating labels and annotations of SubNamespace for sub1 namespace") - sn.Spec.Labels["team"] = "tama" - sn.Spec.Annotations["memo"] = "tama" - err = k8sClient.Update(ctx, sn) - Expect(err).NotTo(HaveOccurred()) - Eventually(func() error { - sub1 := &corev1.Namespace{} - err := k8sClient.Get(ctx, client.ObjectKey{Name: "sub1"}, sub1) - if err != nil { - return err - } - if sub1.Labels["team"] != "tama" { - return errors.New("team label is not tama") - } - if sub1.Annotations["memo"] != "tama" { - return errors.New("memo annotation is not tama") - } - return nil - }).Should(Succeed()) - - Eventually(func() error { - sub2 := &corev1.Namespace{} - err := k8sClient.Get(ctx, client.ObjectKey{Name: "sub2"}, sub2) - if err != nil { - return err - } - if sub2.Labels["team"] != "tama" { - return errors.New("team label is not tama") - } - if sub2.Annotations["memo"] != "tama" { - return errors.New("memo annotation is not tama") - } - return nil - }).Should(Succeed()) + Expect(komega.Update(sn, func() { + sn.Spec.Labels["team"] = "tama" + sn.Spec.Annotations["memo"] = "tama" + })()).To(Succeed()) + Eventually(komega.Object(sub1)).Should(And( + HaveField("Labels", HaveKeyWithValue("team", "tama")), + HaveField("Annotations", HaveKeyWithValue("memo", "tama")), + )) + Eventually(komega.Object(sub2)).Should(And( + HaveField("Labels", HaveKeyWithValue("team", "tama")), + HaveField("Annotations", HaveKeyWithValue("memo", "tama")), + )) }) }) diff --git a/controllers/propagate_test.go b/controllers/propagate_test.go index 11991b2..caa9f5e 100644 --- a/controllers/propagate_test.go +++ b/controllers/propagate_test.go @@ -13,10 +13,10 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/intstr" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/envtest/komega" "sigs.k8s.io/controller-runtime/pkg/metrics/server" ) @@ -42,15 +42,12 @@ var _ = Describe("SubNamespace controller", func() { BeforeEach(func() { for _, ns := range []string{rootNS, sub1NS, sub2NS, sub1SubNS} { - err := k8sClient.DeleteAllOf(ctx, &corev1.ConfigMap{}, client.InNamespace(ns)) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.DeleteAllOf(ctx, &corev1.ConfigMap{}, client.InNamespace(ns))).To(Succeed()) } svcList := &corev1.ServiceList{} - err := k8sClient.List(ctx, svcList) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.List(ctx, svcList)).To(Succeed()) for i := range svcList.Items { - err := k8sClient.Delete(ctx, &svcList.Items[i]) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Delete(ctx, &svcList.Items[i])).To(Succeed()) } mgr, err := ctrl.NewManager(k8sCfg, ctrl.Options{ @@ -93,38 +90,35 @@ var _ = Describe("SubNamespace controller", func() { svc1.Annotations = map[string]string{constants.AnnPropagate: constants.PropagateCreate} svc1.Spec.ClusterIP = "None" svc1.Spec.Ports = []corev1.ServicePort{{Port: 3333, TargetPort: intstr.FromInt(3333)}} - err := k8sClient.Create(ctx, svc1) - Expect(err).NotTo(HaveOccurred()) - svc1.Status.Conditions = []metav1.Condition{{ - Type: "foo", - Status: metav1.ConditionTrue, - LastTransitionTime: metav1.Now(), - Reason: "Foo", - Message: "blah", - }} - err = k8sClient.Status().Update(ctx, svc1) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, svc1)).To(Succeed()) + Expect(komega.UpdateStatus(svc1, func() { + svc1.Status.Conditions = []metav1.Condition{{ + Type: "foo", + Status: metav1.ConditionTrue, + LastTransitionTime: metav1.Now(), + Reason: "Foo", + Message: "blah", + }} + })()).To(Succeed()) svc2 := &corev1.Service{} svc2.Namespace = rootNS svc2.Name = "svc2" svc2.Spec.Ports = []corev1.ServicePort{{Port: 3333, TargetPort: intstr.FromInt(3333)}} - err = k8sClient.Create(ctx, svc2) - Expect(err).NotTo(HaveOccurred()) - - var svc1Sub1, svc1Sub2, svc1Sub1Sub *corev1.Service - Eventually(func() error { - svc1Sub1 = &corev1.Service{} - return k8sClient.Get(ctx, client.ObjectKey{Namespace: sub1NS, Name: "svc1"}, svc1Sub1) - }).Should(Succeed()) - Eventually(func() error { - svc1Sub2 = &corev1.Service{} - return k8sClient.Get(ctx, client.ObjectKey{Namespace: sub2NS, Name: "svc1"}, svc1Sub2) - }).Should(Succeed()) - Eventually(func() error { - svc1Sub1Sub = &corev1.Service{} - return k8sClient.Get(ctx, client.ObjectKey{Namespace: sub1SubNS, Name: "svc1"}, svc1Sub1Sub) - }).Should(Succeed()) + Expect(k8sClient.Create(ctx, svc2)).To(Succeed()) + + svc1Sub1 := &corev1.Service{} + svc1Sub1.Name = "svc1" + svc1Sub1.Namespace = sub1NS + Eventually(komega.Get(svc1Sub1)).Should(Succeed()) + svc1Sub2 := &corev1.Service{} + svc1Sub2.Name = "svc1" + svc1Sub2.Namespace = sub2NS + Eventually(komega.Get(svc1Sub2)).Should(Succeed()) + svc1Sub1Sub := &corev1.Service{} + svc1Sub1Sub.Name = "svc1" + svc1Sub1Sub.Namespace = sub1SubNS + Eventually(komega.Get(svc1Sub1Sub)).Should(Succeed()) Expect(svc1Sub1.Annotations).To(HaveKeyWithValue(constants.AnnFrom, rootNS)) Expect(svc1Sub1.Spec.Ports).To(HaveLen(1)) Expect(svc1Sub1.Spec.Ports[0].Port).To(BeNumerically("==", 3333)) @@ -136,72 +130,38 @@ var _ = Describe("SubNamespace controller", func() { Expect(svc1Sub1Sub.Spec.Ports[0].Port).To(BeNumerically("==", 3333)) svc2Sub1 := &corev1.Service{} - err = k8sClient.Get(ctx, client.ObjectKey{Namespace: sub1NS, Name: "svc2"}, svc2Sub1) - Expect(apierrors.IsNotFound(err)).To(BeTrue()) + svc2Sub1.Name = "svc2" + svc2Sub1.Namespace = sub1NS + Expect(komega.Get(svc2Sub1)()).Should(WithTransform(apierrors.IsNotFound, BeTrue())) By("deleting a sub-resource to check that Accurate re-creates it") uid := svc1Sub2.UID - err = k8sClient.Delete(ctx, svc1Sub2) - Expect(err).NotTo(HaveOccurred()) - Eventually(func() types.UID { - svc := &corev1.Service{} - if err := k8sClient.Get(ctx, client.ObjectKey{Namespace: sub2NS, Name: "svc1"}, svc); err != nil { - return uid - } - return svc.UID - }).ShouldNot(Equal(uid)) + Expect(k8sClient.Delete(ctx, svc1Sub2)).To(Succeed()) + Eventually(komega.Object(svc1Sub2)).Should(HaveField("UID", Not(Equal(uid)))) By("updating a sub-resource to check that Accurate won't fix it") - svc1Sub1.Annotations["hoge"] = "fuga" - err = k8sClient.Update(ctx, svc1Sub1) - Expect(err).NotTo(HaveOccurred()) + Expect(komega.Update(svc1Sub1, func() { + svc1Sub1.Annotations["hoge"] = "fuga" + })()).To(Succeed()) - Eventually(func() string { - svc1Sub1 = &corev1.Service{} - if err := k8sClient.Get(ctx, client.ObjectKey{Namespace: sub1NS, Name: "svc1"}, svc1Sub1); err != nil { - return "" - } - return svc1Sub1.Annotations["hoge"] - }).Should(Equal("fuga")) - Consistently(func() string { - svc1Sub1 = &corev1.Service{} - if err := k8sClient.Get(ctx, client.ObjectKey{Namespace: sub1NS, Name: "svc1"}, svc1Sub1); err != nil { - return "" - } - return svc1Sub1.Annotations["hoge"] - }).Should(Equal("fuga")) + Eventually(komega.Object(svc1Sub1)).Should(HaveField("Annotations", HaveKeyWithValue("hoge", "fuga"))) + Consistently(komega.Object(svc1Sub1)).Should(HaveField("Annotations", HaveKeyWithValue("hoge", "fuga"))) By("changing a sub-resource to a non-sub-resource") - svc1Sub1Sub.Annotations = map[string]string{ - constants.AnnPropagate: constants.PropagateUpdate, - } - err = k8sClient.Update(ctx, svc1Sub1Sub) - Expect(err).NotTo(HaveOccurred()) - - Eventually(func() string { - svc1Sub1Sub = &corev1.Service{} - if err := k8sClient.Get(ctx, client.ObjectKey{Namespace: sub1SubNS, Name: "svc1"}, svc1Sub1Sub); err != nil { - return "" + Expect(komega.Update(svc1Sub1Sub, func() { + svc1Sub1Sub.Annotations = map[string]string{ + constants.AnnPropagate: constants.PropagateUpdate, } - return svc1Sub1Sub.Annotations[constants.AnnPropagate] - }).Should(Equal(constants.PropagateUpdate)) - Consistently(func() string { - svc1Sub1Sub = &corev1.Service{} - if err := k8sClient.Get(ctx, client.ObjectKey{Namespace: sub1SubNS, Name: "svc1"}, svc1Sub1Sub); err != nil { - return "" - } - return svc1Sub1Sub.Annotations[constants.AnnPropagate] - }).Should(Equal(constants.PropagateUpdate)) + })()).To(Succeed()) + + Eventually(komega.Object(svc1Sub1Sub)).Should(HaveField("Annotations", HaveKeyWithValue(constants.AnnPropagate, constants.PropagateUpdate))) + Consistently(komega.Object(svc1Sub1Sub)).Should(HaveField("Annotations", HaveKeyWithValue(constants.AnnPropagate, constants.PropagateUpdate))) Expect(svc1Sub1Sub.Annotations).NotTo(HaveKey(constants.AnnFrom)) By("deleting the root resource") - err = k8sClient.Delete(ctx, svc1) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Delete(ctx, svc1)).To(Succeed()) - Consistently(func() error { - svc1Sub1 = &corev1.Service{} - return k8sClient.Get(ctx, client.ObjectKey{Namespace: sub1NS, Name: "svc1"}, svc1Sub1) - }).Should(Succeed()) + Consistently(komega.Get(svc1Sub1)).Should(Succeed()) Expect(svc1Sub1.DeletionTimestamp).To(BeNil()) }) @@ -213,49 +173,40 @@ var _ = Describe("SubNamespace controller", func() { svc1.Annotations = map[string]string{constants.AnnPropagate: constants.PropagateCreate} svc1.Spec.ClusterIP = "None" svc1.Spec.Ports = []corev1.ServicePort{{Port: 3333, TargetPort: intstr.FromInt(3333)}} - err := k8sClient.Create(ctx, svc1) - Expect(err).NotTo(HaveOccurred()) - svc1.Status.Conditions = []metav1.Condition{{ - Type: "foo", - Status: metav1.ConditionTrue, - LastTransitionTime: metav1.Now(), - Reason: "Foo", - Message: "blah", - }} - err = k8sClient.Status().Update(ctx, svc1) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, svc1)).To(Succeed()) + Expect(komega.UpdateStatus(svc1, func() { + svc1.Status.Conditions = []metav1.Condition{{ + Type: "foo", + Status: metav1.ConditionTrue, + LastTransitionTime: metav1.Now(), + Reason: "Foo", + Message: "blah", + }} + })()).To(Succeed()) svc2 := &corev1.Service{} svc2.Namespace = tmplNS svc2.Name = "svc2" svc2.Spec.Ports = []corev1.ServicePort{{Port: 3333, TargetPort: intstr.FromInt(3333)}} - err = k8sClient.Create(ctx, svc2) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, svc2)).To(Succeed()) - var svc1Instance *corev1.Service - Eventually(func() error { - svc1Instance = &corev1.Service{} - return k8sClient.Get(ctx, client.ObjectKey{Namespace: instanceNS, Name: "svc1"}, svc1Instance) - }).Should(Succeed()) + svc1Instance := &corev1.Service{} + svc1Instance.Name = "svc1" + svc1Instance.Namespace = instanceNS + Eventually(komega.Get(svc1Instance)).Should(Succeed()) Expect(svc1Instance.Annotations).To(HaveKeyWithValue(constants.AnnFrom, tmplNS)) Expect(svc1Instance.Spec.Ports).To(HaveLen(1)) Expect(svc1Instance.Spec.Ports[0].Port).To(BeNumerically("==", 3333)) svc2Instance := &corev1.Service{} - err = k8sClient.Get(ctx, client.ObjectKey{Namespace: instanceNS, Name: "svc2"}, svc2Instance) - Expect(apierrors.IsNotFound(err)).To(BeTrue()) + svc2Instance.Name = "svc2" + svc2Instance.Namespace = instanceNS + Expect(komega.Get(svc2Instance)()).Should(WithTransform(apierrors.IsNotFound, BeTrue())) By("deleting a sub-resource to check that Accurate re-creates it") uid := svc1Instance.UID - err = k8sClient.Delete(ctx, svc1Instance) - Expect(err).NotTo(HaveOccurred()) - Eventually(func() types.UID { - svc1Instance = &corev1.Service{} - if err := k8sClient.Get(ctx, client.ObjectKey{Namespace: instanceNS, Name: "svc1"}, svc1Instance); err != nil { - return uid - } - return svc1Instance.UID - }).ShouldNot(Equal(uid)) + Expect(k8sClient.Delete(ctx, svc1Instance)).To(Succeed()) + Eventually(komega.Object(svc1Instance)).Should(HaveField("UID", Not(Equal(uid)))) }) It("should propagate resources for mode=update", func() { @@ -266,31 +217,29 @@ var _ = Describe("SubNamespace controller", func() { svc1.Annotations = map[string]string{constants.AnnPropagate: constants.PropagateUpdate} svc1.Spec.ClusterIP = "None" svc1.Spec.Ports = []corev1.ServicePort{{Port: 3333, TargetPort: intstr.FromInt(3333)}} - err := k8sClient.Create(ctx, svc1) - Expect(err).NotTo(HaveOccurred()) - svc1.Status.Conditions = []metav1.Condition{{ - Type: "foo", - Status: metav1.ConditionTrue, - LastTransitionTime: metav1.Now(), - Reason: "Foo", - Message: "blah", - }} - err = k8sClient.Status().Update(ctx, svc1) - Expect(err).NotTo(HaveOccurred()) - - var svc1Sub1, svc1Sub2, svc1Sub1Sub *corev1.Service - Eventually(func() error { - svc1Sub1 = &corev1.Service{} - return k8sClient.Get(ctx, client.ObjectKey{Namespace: sub1NS, Name: "svc1"}, svc1Sub1) - }).Should(Succeed()) - Eventually(func() error { - svc1Sub2 = &corev1.Service{} - return k8sClient.Get(ctx, client.ObjectKey{Namespace: sub2NS, Name: "svc1"}, svc1Sub2) - }).Should(Succeed()) - Eventually(func() error { - svc1Sub1Sub = &corev1.Service{} - return k8sClient.Get(ctx, client.ObjectKey{Namespace: sub1SubNS, Name: "svc1"}, svc1Sub1Sub) - }).Should(Succeed()) + Expect(k8sClient.Create(ctx, svc1)).To(Succeed()) + Expect(komega.UpdateStatus(svc1, func() { + svc1.Status.Conditions = []metav1.Condition{{ + Type: "foo", + Status: metav1.ConditionTrue, + LastTransitionTime: metav1.Now(), + Reason: "Foo", + Message: "blah", + }} + })()).To(Succeed()) + + svc1Sub1 := &corev1.Service{} + svc1Sub1.Name = "svc1" + svc1Sub1.Namespace = sub1NS + Eventually(komega.Get(svc1Sub1)).Should(Succeed()) + svc1Sub2 := &corev1.Service{} + svc1Sub2.Name = "svc1" + svc1Sub2.Namespace = sub2NS + Eventually(komega.Get(svc1Sub2)).Should(Succeed()) + svc1Sub1Sub := &corev1.Service{} + svc1Sub1Sub.Name = "svc1" + svc1Sub1Sub.Namespace = sub1SubNS + Eventually(komega.Get(svc1Sub1Sub)).Should(Succeed()) Expect(svc1Sub1.Annotations).To(HaveKeyWithValue(constants.AnnFrom, rootNS)) Expect(svc1Sub1.Spec.Ports).To(HaveLen(1)) Expect(svc1Sub1.Spec.Ports[0].Port).To(BeNumerically("==", 3333)) @@ -303,60 +252,40 @@ var _ = Describe("SubNamespace controller", func() { By("deleting a sub-resource to check that Accurate re-creates it") uid := svc1Sub2.UID - err = k8sClient.Delete(ctx, svc1Sub2) - Expect(err).NotTo(HaveOccurred()) - Eventually(func() types.UID { - svc := &corev1.Service{} - if err := k8sClient.Get(ctx, client.ObjectKey{Namespace: sub2NS, Name: "svc1"}, svc); err != nil { - return uid - } - return svc.UID - }).ShouldNot(Equal(uid)) + Expect(k8sClient.Delete(ctx, svc1Sub2)).To(Succeed()) + Eventually(komega.Object(svc1Sub2)).Should(HaveField("UID", Not(Equal(uid)))) By("updating a sub-resource to check that Accurate fixes it") - svc1Sub1.Annotations[constants.AnnPropagate] = constants.PropagateCreate - err = k8sClient.Update(ctx, svc1Sub1) - Expect(err).NotTo(HaveOccurred()) + Expect(komega.Update(svc1Sub1, func() { + svc1Sub1.Annotations[constants.AnnPropagate] = constants.PropagateCreate + })()).To(Succeed()) rv := svc1Sub1.ResourceVersion rv2 := svc1Sub1Sub.ResourceVersion - Eventually(func() string { - svc1Sub1 = &corev1.Service{} - if err := k8sClient.Get(ctx, client.ObjectKey{Namespace: sub1NS, Name: "svc1"}, svc1Sub1); err != nil { - return rv - } - return svc1Sub1.ResourceVersion - }).ShouldNot(Equal(rv)) + Eventually(komega.Object(svc1Sub1)).Should(HaveField("ResourceVersion", Not(Equal(rv)))) Expect(svc1Sub1.Annotations).To(HaveKeyWithValue(constants.AnnPropagate, constants.PropagateUpdate)) time.Sleep(100 * time.Millisecond) Expect(svc1Sub1Sub.ResourceVersion).To(Equal(rv2)) By("updating a root resource to check that Accurate propagates the change to sub-resources") - svc1.Labels = map[string]string{"foo": "bar"} - err = k8sClient.Update(ctx, svc1) - Expect(err).NotTo(HaveOccurred()) + Expect(komega.Update(svc1, func() { + svc1.Labels = map[string]string{"foo": "bar"} + })()).To(Succeed()) for _, ns := range []string{sub1NS, sub2NS, sub1SubNS} { - Eventually(func() string { - svc := &corev1.Service{} - if err := k8sClient.Get(ctx, client.ObjectKey{Namespace: ns, Name: "svc1"}, svc); err != nil { - return "" - } - return svc.Labels["foo"] - }).Should(Equal("bar")) + svc := &corev1.Service{} + svc.Name = "svc1" + svc.Namespace = ns + Eventually(komega.Object(svc)).Should(HaveField("Labels", HaveKeyWithValue("foo", "bar"))) } By("deleting a root resource to check that Accurate cascades the deletion") - err = k8sClient.Delete(ctx, svc1) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Delete(ctx, svc1)).To(Succeed()) for _, ns := range []string{sub1NS, sub2NS, sub1SubNS} { - Eventually(func() bool { - svc := &corev1.Service{} - if err := k8sClient.Get(ctx, client.ObjectKey{Namespace: ns, Name: "svc1"}, svc); err != nil { - return apierrors.IsNotFound(err) - } - return false - }).Should(BeTrue()) + svc := &corev1.Service{} + svc.Name = "svc1" + svc.Namespace = ns + Eventually(komega.Get(svc)).Should(WithTransform(apierrors.IsNotFound, BeTrue())) } }) @@ -367,15 +296,13 @@ var _ = Describe("SubNamespace controller", func() { //lint:ignore SA1019 subject for removal cm1.Annotations = map[string]string{constants.AnnPropagateGenerated: constants.PropagateUpdate} cm1.Data = map[string]string{"foo": "bar"} - err := k8sClient.Create(ctx, cm1) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, cm1)).To(Succeed()) cm2 := &corev1.ConfigMap{} cm2.Namespace = rootNS cm2.Name = "cm-no-generate" cm2.Data = map[string]string{"abc": "def"} - err = k8sClient.Create(ctx, cm2) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, cm2)).To(Succeed()) svc1 := &corev1.Service{} svc1.Namespace = rootNS @@ -383,35 +310,21 @@ var _ = Describe("SubNamespace controller", func() { ctrl.SetControllerReference(cm1, svc1, scheme) svc1.Spec.ClusterIP = "None" svc1.Spec.Ports = []corev1.ServicePort{{Port: 3333, TargetPort: intstr.FromInt(3333)}} - err = k8sClient.Create(ctx, svc1) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, svc1)).To(Succeed()) - Eventually(func() string { - svc1 = &corev1.Service{} - if err := k8sClient.Get(ctx, client.ObjectKey{Namespace: rootNS, Name: "svc1"}, svc1); err != nil { - return "" - } - return svc1.Annotations[constants.AnnPropagate] - }).Should(Equal(constants.PropagateUpdate)) + Eventually(komega.Object(svc1)).Should(HaveField("Annotations", HaveKeyWithValue(constants.AnnPropagate, constants.PropagateUpdate))) //lint:ignore SA1019 subject for removal Expect(svc1.Annotations).NotTo(HaveKey(constants.AnnGenerated)) svc2 := &corev1.Service{} svc2.Namespace = rootNS svc2.Name = "svc2" - ctrl.SetControllerReference(cm2, svc2, scheme) + Expect(ctrl.SetControllerReference(cm2, svc2, scheme)).To(Succeed()) svc2.Spec.ClusterIP = "None" svc2.Spec.Ports = []corev1.ServicePort{{Port: 3333, TargetPort: intstr.FromInt(3333)}} - err = k8sClient.Create(ctx, svc2) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, svc2)).To(Succeed()) - Eventually(func() string { - svc2 = &corev1.Service{} - if err := k8sClient.Get(ctx, client.ObjectKey{Namespace: rootNS, Name: "svc2"}, svc2); err != nil { - return "" - } - //lint:ignore SA1019 subject for removal - return svc2.Annotations[constants.AnnGenerated] - }).Should(Equal(notGenerated)) + //lint:ignore SA1019 subject for removal + Eventually(komega.Object(svc2)).Should(HaveField("Annotations", HaveKeyWithValue(constants.AnnGenerated, notGenerated))) }) }) diff --git a/controllers/subnamespace_controller_test.go b/controllers/subnamespace_controller_test.go index 220a5cc..da7c368 100644 --- a/controllers/subnamespace_controller_test.go +++ b/controllers/subnamespace_controller_test.go @@ -9,11 +9,10 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/envtest/komega" "sigs.k8s.io/controller-runtime/pkg/metrics/server" ) @@ -54,71 +53,43 @@ var _ = Describe("SubNamespace controller", func() { It("should create and delete sub namespaces", func() { ns := &corev1.Namespace{} ns.Name = "test1" - err := k8sClient.Create(ctx, ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, ns)).To(Succeed()) sn := &accuratev2alpha1.SubNamespace{} sn.Namespace = "test1" sn.Name = "test1-sub1" sn.Finalizers = []string{constants.Finalizer} - err = k8sClient.Create(ctx, sn) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, sn)).To(Succeed()) - var sub1 *corev1.Namespace - Eventually(func() error { - sub1 = &corev1.Namespace{} - return k8sClient.Get(ctx, client.ObjectKey{Name: "test1-sub1"}, sub1) - }).Should(Succeed()) + sub1 := &corev1.Namespace{} + sub1.Name = "test1-sub1" + Eventually(komega.Get(sub1)).Should(Succeed()) Expect(sub1.Labels).To(HaveKeyWithValue(constants.LabelCreatedBy, "accurate")) Expect(sub1.Labels).To(HaveKeyWithValue(constants.LabelParent, "test1")) - Eventually(func() int64 { - sn = &accuratev2alpha1.SubNamespace{} - err = k8sClient.Get(ctx, client.ObjectKey{Namespace: "test1", Name: "test1-sub1"}, sn) - if err != nil { - return 0 - } - return sn.Status.ObservedGeneration - }).Should(BeNumerically(">", 0)) + Eventually(komega.Object(sn)).Should(HaveField("Status.ObservedGeneration", BeNumerically(">", 0))) Expect(sn.Status.Conditions).To(BeEmpty()) - err = k8sClient.Delete(ctx, sn) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Delete(ctx, sn)).To(Succeed()) - Eventually(func() bool { - sub1 = &corev1.Namespace{} - err := k8sClient.Get(ctx, client.ObjectKey{Name: "test1-sub1"}, sub1) - if err != nil { - return apierrors.IsNotFound(err) - } - return sub1.DeletionTimestamp != nil - }).Should(BeTrue()) + Eventually(komega.Object(sub1)).Should(HaveField("DeletionTimestamp", Not(BeNil()))) }) It("should detect conflicts", func() { ns := &corev1.Namespace{} ns.Name = "test2" - err := k8sClient.Create(ctx, ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, ns)).To(Succeed()) ns2 := &corev1.Namespace{} ns2.Name = "test2-sub1" - err = k8sClient.Create(ctx, ns2) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, ns2)).To(Succeed()) sn := &accuratev2alpha1.SubNamespace{} sn.Namespace = "test2" sn.Name = "test2-sub1" - err = k8sClient.Create(ctx, sn) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, sn)).To(Succeed()) - Eventually(func() int64 { - sn = &accuratev2alpha1.SubNamespace{} - if err := k8sClient.Get(ctx, client.ObjectKey{Namespace: "test2", Name: "test2-sub1"}, sn); err != nil { - return 0 - } - return sn.Status.ObservedGeneration - }).Should(BeNumerically(">", 0)) + Eventually(komega.Object(sn)).Should(HaveField("Status.ObservedGeneration", BeNumerically(">", 0))) Expect(sn.Status.Conditions).To(HaveLen(1)) Expect(sn.Status.Conditions[0].Reason).To(Equal(accuratev2alpha1.SubNamespaceConflict)) }) @@ -126,68 +97,45 @@ var _ = Describe("SubNamespace controller", func() { It("should not delete a conflicting sub namespace", func() { ns := &corev1.Namespace{} ns.Name = "test3" - err := k8sClient.Create(ctx, ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, ns)).To(Succeed()) sn := &accuratev2alpha1.SubNamespace{} sn.Namespace = "test3" sn.Name = "test3-sub1" sn.Finalizers = []string{constants.Finalizer} - err = k8sClient.Create(ctx, sn) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, sn)).To(Succeed()) - var sub1 *corev1.Namespace - Eventually(func() error { - sub1 = &corev1.Namespace{} - return k8sClient.Get(ctx, client.ObjectKey{Name: "test3-sub1"}, sub1) - }).Should(Succeed()) + sub1 := &corev1.Namespace{} + sub1.Name = "test3-sub1" + Eventually(komega.Get(sub1)).Should(Succeed()) - sub1.Labels[constants.LabelParent] = "foo" - err = k8sClient.Update(ctx, sub1) - Expect(err).NotTo(HaveOccurred()) + Expect(komega.Update(sub1, func() { + sub1.Labels[constants.LabelParent] = "foo" + })()).To(Succeed()) - Eventually(func() []metav1.Condition { - sn = &accuratev2alpha1.SubNamespace{} - err = k8sClient.Get(ctx, client.ObjectKey{Namespace: "test3", Name: "test3-sub1"}, sn) - if err != nil { - return nil - } - return sn.Status.Conditions - }).Should(HaveLen(1)) + Eventually(komega.Object(sn)).Should(HaveField("Status.Conditions", HaveLen(1))) Expect(sn.Status.Conditions[0].Reason).To(Equal(accuratev2alpha1.SubNamespaceConflict)) - err = k8sClient.Delete(ctx, sn) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Delete(ctx, sn)).To(Succeed()) - Consistently(func() bool { - sub1 = &corev1.Namespace{} - if err := k8sClient.Get(ctx, client.ObjectKey{Name: "test3-sub1"}, sub1); err != nil { - return false - } - return sub1.DeletionTimestamp == nil - }).Should(BeTrue()) + Consistently(komega.Object(sub1)).Should(HaveField("DeletionTimestamp", BeNil())) }) It("should re-create a subnamespace if it is deleted", func() { ns := &corev1.Namespace{} ns.Name = "test4" - err := k8sClient.Create(ctx, ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, ns)).To(Succeed()) sn := &accuratev2alpha1.SubNamespace{} sn.Namespace = "test4" sn.Name = "test4-sub1" - err = k8sClient.Create(ctx, sn) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, sn)).To(Succeed()) - var sub1 *corev1.Namespace - Eventually(func() error { - sub1 = &corev1.Namespace{} - return k8sClient.Get(ctx, client.ObjectKey{Name: "test4-sub1"}, sub1) - }).Should(Succeed()) + sub1 := &corev1.Namespace{} + sub1.Name = "test4-sub1" + Eventually(komega.Get(sub1)).Should(Succeed()) - err = k8sClient.Delete(ctx, sub1) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Delete(ctx, sub1)).To(Succeed()) uid := sub1.UID sub1 = &corev1.Namespace{} @@ -197,13 +145,6 @@ var _ = Describe("SubNamespace controller", func() { _, err = cs.CoreV1().Namespaces().Finalize(ctx, sub1, metav1.UpdateOptions{}) Expect(err).NotTo(HaveOccurred()) - Eventually(func() bool { - sub1 = &corev1.Namespace{} - err := k8sClient.Get(ctx, client.ObjectKey{Name: "test4-sub1"}, sub1) - if err != nil { - return false - } - return sub1.UID != uid - }).Should(BeTrue()) + Eventually(komega.Object(sub1)).Should(HaveField("UID", Not(Equal(uid)))) }) }) diff --git a/controllers/suite_test.go b/controllers/suite_test.go index fa7c640..3420e82 100644 --- a/controllers/suite_test.go +++ b/controllers/suite_test.go @@ -15,6 +15,7 @@ import ( "k8s.io/client-go/rest" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/envtest" + "sigs.k8s.io/controller-runtime/pkg/envtest/komega" logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/log/zap" @@ -79,43 +80,38 @@ var _ = BeforeSuite(func() { k8sClient, err = client.New(cfg, client.Options{Scheme: scheme}) Expect(err).NotTo(HaveOccurred()) Expect(k8sClient).NotTo(BeNil()) + komega.SetClient(k8sClient) // prepare resources ns := &corev1.Namespace{} ns.Name = "prop-root" ns.Labels = map[string]string{constants.LabelType: constants.NSTypeRoot} - err = k8sClient.Create(context.Background(), ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(context.Background(), ns)).To(Succeed()) ns = &corev1.Namespace{} ns.Name = "prop-sub1" ns.Labels = map[string]string{constants.LabelParent: "prop-root"} - err = k8sClient.Create(context.Background(), ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(context.Background(), ns)).To(Succeed()) ns = &corev1.Namespace{} ns.Name = "prop-sub2" ns.Labels = map[string]string{constants.LabelParent: "prop-root"} - err = k8sClient.Create(context.Background(), ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(context.Background(), ns)).To(Succeed()) ns = &corev1.Namespace{} ns.Name = "prop-sub1-sub" ns.Labels = map[string]string{constants.LabelParent: "prop-sub1"} - err = k8sClient.Create(context.Background(), ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(context.Background(), ns)).To(Succeed()) ns = &corev1.Namespace{} ns.Name = "prop-tmpl" ns.Labels = map[string]string{constants.LabelType: constants.NSTypeTemplate} - err = k8sClient.Create(context.Background(), ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(context.Background(), ns)).To(Succeed()) ns = &corev1.Namespace{} ns.Name = "prop-instance" ns.Labels = map[string]string{constants.LabelTemplate: "prop-tmpl"} - err = k8sClient.Create(context.Background(), ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(context.Background(), ns)).To(Succeed()) }) diff --git a/hooks/namespace_test.go b/hooks/namespace_test.go index 02a0a58..6410976 100644 --- a/hooks/namespace_test.go +++ b/hooks/namespace_test.go @@ -15,12 +15,11 @@ var _ = Describe("Namespace webhook", func() { It("should allow creating a normal namespace", func() { ns := &corev1.Namespace{} ns.Name = "normal" - err := k8sClient.Create(ctx, ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, ns)).To(Succeed()) By("referencing a non-template as a template") ns.Labels = map[string]string{constants.LabelTemplate: "default"} - err = k8sClient.Update(ctx, ns) + err := k8sClient.Update(ctx, ns) Expect(err).To(HaveOccurred()) }) @@ -28,20 +27,18 @@ var _ = Describe("Namespace webhook", func() { ns := &corev1.Namespace{} ns.Name = "tmpl1" ns.Labels = map[string]string{constants.LabelType: constants.NSTypeTemplate} - err := k8sClient.Create(ctx, ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, ns)).To(Succeed()) instance := &corev1.Namespace{} instance.Name = "instance-of-tmpl1" instance.Labels = map[string]string{ constants.LabelTemplate: "tmpl1", } - err = k8sClient.Create(ctx, instance) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, instance)).To(Succeed()) By("removing accurate.cybozu.com/type label from tmpl1") ns.Labels = nil - err = k8sClient.Update(ctx, ns) + err := k8sClient.Update(ctx, ns) Expect(err).To(HaveOccurred()) }) @@ -85,13 +82,12 @@ var _ = Describe("Namespace webhook", func() { ns := &corev1.Namespace{} ns.Name = "non-root-non-sub" ns.Labels = map[string]string{constants.LabelType: "not-a-root"} - err := k8sClient.Create(ctx, ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, ns)).To(Succeed()) sub := &corev1.Namespace{} sub.Name = "sub-of-non-root-non-sub" sub.Labels = map[string]string{constants.LabelParent: "non-root-non-sub"} - err = k8sClient.Create(ctx, sub) + err := k8sClient.Create(ctx, sub) Expect(err).To(HaveOccurred()) }) @@ -99,57 +95,49 @@ var _ = Describe("Namespace webhook", func() { ns := &corev1.Namespace{} ns.Name = "create-root" ns.Labels = map[string]string{constants.LabelType: constants.NSTypeRoot} - err := k8sClient.Create(ctx, ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, ns)).To(Succeed()) sub := &corev1.Namespace{} sub.Name = "sub-of-create-root" sub.Labels = map[string]string{constants.LabelParent: "create-root"} - err = k8sClient.Create(ctx, sub) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, sub)).To(Succeed()) }) It("should allow creating a sub-namespace under another sub-namespace", func() { ns := &corev1.Namespace{} ns.Name = "create-root2" ns.Labels = map[string]string{constants.LabelType: constants.NSTypeRoot} - err := k8sClient.Create(ctx, ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, ns)).To(Succeed()) sub := &corev1.Namespace{} sub.Name = "sub-of-create-root2" sub.Labels = map[string]string{constants.LabelParent: "create-root2"} - err = k8sClient.Create(ctx, sub) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, sub)).To(Succeed()) sub2 := &corev1.Namespace{} sub2.Name = "sub2-of-create-root2" sub2.Labels = map[string]string{constants.LabelParent: "sub-of-create-root2"} - err = k8sClient.Create(ctx, sub2) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, sub2)).To(Succeed()) }) It("should deny updating a sub-namespace that would create a circular reference", func() { ns := &corev1.Namespace{} ns.Name = "non-circular-root" ns.Labels = map[string]string{constants.LabelType: constants.NSTypeRoot} - err := k8sClient.Create(ctx, ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, ns)).To(Succeed()) sub := &corev1.Namespace{} sub.Name = "sub-of-non-circular-root" sub.Labels = map[string]string{constants.LabelParent: "non-circular-root"} - err = k8sClient.Create(ctx, sub) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, sub)).To(Succeed()) sub2 := &corev1.Namespace{} sub2.Name = "sub2-of-non-circular-root" sub2.Labels = map[string]string{constants.LabelParent: "sub-of-non-circular-root"} - err = k8sClient.Create(ctx, sub2) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, sub2)).To(Succeed()) sub.Labels[constants.LabelParent] = "sub2-of-non-circular-root" - err = k8sClient.Update(ctx, sub) + err := k8sClient.Update(ctx, sub) Expect(err).To(HaveOccurred()) }) @@ -157,8 +145,7 @@ var _ = Describe("Namespace webhook", func() { ns := &corev1.Namespace{} ns.Name = "non-circular-root2" ns.Labels = map[string]string{constants.LabelType: constants.NSTypeTemplate} - err := k8sClient.Create(ctx, ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, ns)).To(Succeed()) sub := &corev1.Namespace{} sub.Name = "sub-of-non-circular-root2" @@ -166,8 +153,7 @@ var _ = Describe("Namespace webhook", func() { constants.LabelType: constants.NSTypeTemplate, constants.LabelTemplate: "non-circular-root2", } - err = k8sClient.Create(ctx, sub) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, sub)).To(Succeed()) sub2 := &corev1.Namespace{} sub2.Name = "sub2-of-non-circular-root2" @@ -175,11 +161,10 @@ var _ = Describe("Namespace webhook", func() { constants.LabelType: constants.NSTypeTemplate, constants.LabelTemplate: "sub-of-non-circular-root2", } - err = k8sClient.Create(ctx, sub2) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, sub2)).To(Succeed()) sub.Labels[constants.LabelTemplate] = "sub2-of-non-circular-root2" - err = k8sClient.Update(ctx, sub) + err := k8sClient.Update(ctx, sub) Expect(err).To(HaveOccurred()) }) @@ -187,8 +172,7 @@ var _ = Describe("Namespace webhook", func() { tmpl := &corev1.Namespace{} tmpl.Name = "dusht-tmpl" tmpl.Labels = map[string]string{constants.LabelType: constants.NSTypeTemplate} - err := k8sClient.Create(ctx, tmpl) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, tmpl)).To(Succeed()) ns := &corev1.Namespace{} ns.Name = "template-root" @@ -196,17 +180,15 @@ var _ = Describe("Namespace webhook", func() { constants.LabelType: constants.NSTypeRoot, constants.LabelTemplate: "dusht-tmpl", } - err = k8sClient.Create(ctx, ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, ns)).To(Succeed()) sub := &corev1.Namespace{} sub.Name = "sub-of-template-root" sub.Labels = map[string]string{constants.LabelParent: "template-root"} - err = k8sClient.Create(ctx, sub) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, sub)).To(Succeed()) sub.Labels[constants.LabelTemplate] = "dusht-tmpl" - err = k8sClient.Update(ctx, sub) + err := k8sClient.Update(ctx, sub) Expect(err).To(HaveOccurred()) }) @@ -214,17 +196,15 @@ var _ = Describe("Namespace webhook", func() { ns := &corev1.Namespace{} ns.Name = "root-of-sub-mark" ns.Labels = map[string]string{constants.LabelType: constants.NSTypeRoot} - err := k8sClient.Create(ctx, ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, ns)).To(Succeed()) sub := &corev1.Namespace{} sub.Name = "sub-of-root-of-sub-mark" sub.Labels = map[string]string{constants.LabelParent: "root-of-sub-mark"} - err = k8sClient.Create(ctx, sub) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, sub)).To(Succeed()) sub.Labels[constants.LabelType] = constants.NSTypeRoot - err = k8sClient.Update(ctx, sub) + err := k8sClient.Update(ctx, sub) Expect(err).To(HaveOccurred()) }) @@ -232,23 +212,20 @@ var _ = Describe("Namespace webhook", func() { ns := &corev1.Namespace{} ns.Name = "root-after-non-root" ns.Labels = map[string]string{constants.LabelType: constants.NSTypeRoot} - err := k8sClient.Create(ctx, ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, ns)).To(Succeed()) sub := &corev1.Namespace{} sub.Name = "sub-of-root-after-non-root" sub.Labels = map[string]string{constants.LabelParent: "root-after-non-root"} - err = k8sClient.Create(ctx, sub) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, sub)).To(Succeed()) sub2 := &corev1.Namespace{} sub2.Name = "sub2-of-root-after-non-root" sub2.Labels = map[string]string{constants.LabelParent: "sub-of-root-after-non-root"} - err = k8sClient.Create(ctx, sub2) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, sub2)).To(Succeed()) delete(ns.Labels, constants.LabelType) - err = k8sClient.Update(ctx, ns) + err := k8sClient.Update(ctx, ns) Expect(err).To(HaveOccurred()) delete(sub.Labels, constants.LabelParent) @@ -260,29 +237,25 @@ var _ = Describe("Namespace webhook", func() { ns := &corev1.Namespace{} ns.Name = "root-after-non-root3" ns.Labels = map[string]string{constants.LabelType: constants.NSTypeRoot} - err := k8sClient.Create(ctx, ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, ns)).To(Succeed()) ns.Labels = nil - err = k8sClient.Update(ctx, ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Update(ctx, ns)).To(Succeed()) }) It("should deny updating a template namespace having one or more instances that would become a non-template", func() { ns := &corev1.Namespace{} ns.Name = "tmpl-to-non-tmpl" ns.Labels = map[string]string{constants.LabelType: constants.NSTypeTemplate} - err := k8sClient.Create(ctx, ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, ns)).To(Succeed()) child := &corev1.Namespace{} child.Name = "child-of-tmpl-to-non-tmpl" child.Labels = map[string]string{constants.LabelTemplate: "tmpl-to-non-tmpl"} - err = k8sClient.Create(ctx, child) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, child)).To(Succeed()) delete(ns.Labels, constants.LabelType) - err = k8sClient.Update(ctx, ns) + err := k8sClient.Update(ctx, ns) Expect(err).To(HaveOccurred()) }) @@ -290,71 +263,60 @@ var _ = Describe("Namespace webhook", func() { ns := &corev1.Namespace{} ns.Name = "tmpl-to-non-tmpl2" ns.Labels = map[string]string{constants.LabelType: constants.NSTypeTemplate} - err := k8sClient.Create(ctx, ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, ns)).To(Succeed()) delete(ns.Labels, constants.LabelType) - err = k8sClient.Update(ctx, ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Update(ctx, ns)).To(Succeed()) }) It("should allow turning a sub-namespace w/o children into a normal namespace", func() { ns := &corev1.Namespace{} ns.Name = "root-of-depth1" ns.Labels = map[string]string{constants.LabelType: constants.NSTypeRoot} - err := k8sClient.Create(ctx, ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, ns)).To(Succeed()) sub := &corev1.Namespace{} sub.Name = "sub-of-root-of-depth1" sub.Labels = map[string]string{constants.LabelParent: "root-of-depth1"} - err = k8sClient.Create(ctx, sub) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, sub)).To(Succeed()) sub.Labels = nil - err = k8sClient.Update(ctx, sub) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Update(ctx, sub)).To(Succeed()) }) It("should allow turning a sub-namespace w/ children into a root namespace", func() { ns := &corev1.Namespace{} ns.Name = "root-for-sub-to-root" ns.Labels = map[string]string{constants.LabelType: constants.NSTypeRoot} - err := k8sClient.Create(ctx, ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, ns)).To(Succeed()) sub := &corev1.Namespace{} sub.Name = "sub-of-root-for-sub-to-root" sub.Labels = map[string]string{constants.LabelParent: "root-for-sub-to-root"} - err = k8sClient.Create(ctx, sub) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, sub)).To(Succeed()) sub2 := &corev1.Namespace{} sub2.Name = "sub2-of-root-for-sub-to-root" sub2.Labels = map[string]string{constants.LabelParent: "sub-of-root-for-sub-to-root"} - err = k8sClient.Create(ctx, sub2) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, sub2)).To(Succeed()) sub.Labels = map[string]string{constants.LabelType: constants.NSTypeRoot} - err = k8sClient.Update(ctx, sub) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Update(ctx, sub)).To(Succeed()) }) It("should deny changing a sub-namespace into a dangling sub-namespace", func() { ns := &corev1.Namespace{} ns.Name = "dangling-root" ns.Labels = map[string]string{constants.LabelType: constants.NSTypeRoot} - err := k8sClient.Create(ctx, ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, ns)).To(Succeed()) sub := &corev1.Namespace{} sub.Name = "sub-of-dangling-root" sub.Labels = map[string]string{constants.LabelParent: "dangling-root"} - err = k8sClient.Create(ctx, sub) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, sub)).To(Succeed()) sub.Labels[constants.LabelParent] = "none" - err = k8sClient.Update(ctx, sub) + err := k8sClient.Update(ctx, sub) Expect(err).To(HaveOccurred()) }) @@ -362,17 +324,15 @@ var _ = Describe("Namespace webhook", func() { ns := &corev1.Namespace{} ns.Name = "dangling-root2" ns.Labels = map[string]string{constants.LabelType: constants.NSTypeTemplate} - err := k8sClient.Create(ctx, ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, ns)).To(Succeed()) sub := &corev1.Namespace{} sub.Name = "sub-of-dangling-root2" sub.Labels = map[string]string{constants.LabelTemplate: "dangling-root2"} - err = k8sClient.Create(ctx, sub) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, sub)).To(Succeed()) sub.Labels[constants.LabelTemplate] = "none" - err = k8sClient.Update(ctx, sub) + err := k8sClient.Update(ctx, sub) Expect(err).To(HaveOccurred()) }) @@ -380,22 +340,19 @@ var _ = Describe("Namespace webhook", func() { ns := &corev1.Namespace{} ns.Name = "move-root" ns.Labels = map[string]string{constants.LabelType: constants.NSTypeRoot} - err := k8sClient.Create(ctx, ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, ns)).To(Succeed()) sub := &corev1.Namespace{} sub.Name = "sub-of-move-root" sub.Labels = map[string]string{constants.LabelParent: "move-root"} - err = k8sClient.Create(ctx, sub) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, sub)).To(Succeed()) nonRoot := &corev1.Namespace{} nonRoot.Name = "move-non-root-non-sub" - err = k8sClient.Create(ctx, nonRoot) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, nonRoot)).To(Succeed()) sub.Labels[constants.LabelParent] = "move-non-root-non-sub" - err = k8sClient.Update(ctx, sub) + err := k8sClient.Update(ctx, sub) Expect(err).To(HaveOccurred()) }) @@ -403,18 +360,16 @@ var _ = Describe("Namespace webhook", func() { ns := &corev1.Namespace{} ns.Name = "delete-root" ns.Labels = map[string]string{constants.LabelType: constants.NSTypeRoot} - err := k8sClient.Create(ctx, ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, ns)).To(Succeed()) sub := &corev1.Namespace{} sub.Name = "sub-of-delete-root" sub.Labels = map[string]string{constants.LabelParent: "delete-root"} - err = k8sClient.Create(ctx, sub) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, sub)).To(Succeed()) ns = &corev1.Namespace{} ns.Name = "delete-root" - err = k8sClient.Delete(ctx, ns) + err := k8sClient.Delete(ctx, ns) Expect(err).To(HaveOccurred()) }) @@ -422,24 +377,21 @@ var _ = Describe("Namespace webhook", func() { ns := &corev1.Namespace{} ns.Name = "delete-root2" ns.Labels = map[string]string{constants.LabelType: constants.NSTypeRoot} - err := k8sClient.Create(ctx, ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, ns)).To(Succeed()) sub := &corev1.Namespace{} sub.Name = "sub-of-delete-root2" sub.Labels = map[string]string{constants.LabelParent: "delete-root2"} - err = k8sClient.Create(ctx, sub) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, sub)).To(Succeed()) sub2 := &corev1.Namespace{} sub2.Name = "sub2-of-delete-root2" sub2.Labels = map[string]string{constants.LabelParent: "sub-of-delete-root2"} - err = k8sClient.Create(ctx, sub2) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, sub2)).To(Succeed()) sub = &corev1.Namespace{} sub.Name = "sub-of-delete-root2" - err = k8sClient.Delete(ctx, sub) + err := k8sClient.Delete(ctx, sub) Expect(err).To(HaveOccurred()) }) @@ -447,16 +399,14 @@ var _ = Describe("Namespace webhook", func() { ns := &corev1.Namespace{} ns.Name = "delete-tmpl1" ns.Labels = map[string]string{constants.LabelType: constants.NSTypeTemplate} - err := k8sClient.Create(ctx, ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, ns)).To(Succeed()) sub := &corev1.Namespace{} sub.Name = "sub-of-delete-tmpl1" sub.Labels = map[string]string{constants.LabelTemplate: "delete-tmpl1"} - err = k8sClient.Create(ctx, sub) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, sub)).To(Succeed()) - err = k8sClient.Delete(ctx, ns) + err := k8sClient.Delete(ctx, ns) Expect(err).To(HaveOccurred()) }) @@ -464,56 +414,47 @@ var _ = Describe("Namespace webhook", func() { ns := &corev1.Namespace{} ns.Name = "delete-root3" ns.Labels = map[string]string{constants.LabelType: constants.NSTypeRoot} - err := k8sClient.Create(ctx, ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, ns)).To(Succeed()) sub := &corev1.Namespace{} sub.Name = "sub-of-delete-root3" sub.Labels = map[string]string{constants.LabelParent: "delete-root3"} - err = k8sClient.Create(ctx, sub) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, sub)).To(Succeed()) sub = &corev1.Namespace{} sub.Name = "sub-of-delete-root3" - err = k8sClient.Delete(ctx, sub) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Delete(ctx, sub)).To(Succeed()) }) It("should allow deleting a root namespace w/o children", func() { ns := &corev1.Namespace{} ns.Name = "delete-root4" ns.Labels = map[string]string{constants.LabelType: constants.NSTypeRoot} - err := k8sClient.Create(ctx, ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, ns)).To(Succeed()) ns = &corev1.Namespace{} ns.Name = "delete-root4" - err = k8sClient.Delete(ctx, ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Delete(ctx, ns)).To(Succeed()) }) It("should allow deleting a non-root and non-sub namespace", func() { ns := &corev1.Namespace{} ns.Name = "delete-root5" - err := k8sClient.Create(ctx, ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, ns)).To(Succeed()) ns = &corev1.Namespace{} ns.Name = "delete-root5" - err = k8sClient.Delete(ctx, ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Delete(ctx, ns)).To(Succeed()) }) It("should allow deleting a template namespace w/o instances", func() { ns := &corev1.Namespace{} ns.Name = "delete-tmpl2" ns.Labels = map[string]string{constants.LabelType: constants.NSTypeTemplate} - err := k8sClient.Create(ctx, ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, ns)).To(Succeed()) ns = &corev1.Namespace{} ns.Name = "delete-tmpl2" - err = k8sClient.Delete(ctx, ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Delete(ctx, ns)).To(Succeed()) }) }) diff --git a/hooks/subnamespace_test.go b/hooks/subnamespace_test.go index f196a8a..eb8d5c0 100644 --- a/hooks/subnamespace_test.go +++ b/hooks/subnamespace_test.go @@ -21,13 +21,12 @@ var _ = Describe("SubNamespace webhook", func() { It("should deny creation of SubNamespace in a namespace that is neither root nor subnamespace", func() { ns := &corev1.Namespace{} ns.Name = "ns1" - err := k8sClient.Create(ctx, ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, ns)).To(Succeed()) sn := &accuratev1.SubNamespace{} sn.Namespace = "ns1" sn.Name = "foo" - err = k8sClient.Create(ctx, sn) + err := k8sClient.Create(ctx, sn) Expect(err).To(HaveOccurred()) Expect(errors.ReasonForError(err)).Should(Equal(metav1.StatusReasonForbidden)) }) @@ -36,27 +35,23 @@ var _ = Describe("SubNamespace webhook", func() { ns := &corev1.Namespace{} ns.Name = "ns2" ns.Labels = map[string]string{constants.LabelType: constants.NSTypeRoot} - err := k8sClient.Create(ctx, ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, ns)).To(Succeed()) sn := &accuratev1.SubNamespace{} sn.Namespace = "ns2" sn.Name = "foo" sn.Spec.Labels = map[string]string{"foo": "bar"} sn.Spec.Annotations = map[string]string{"foo": "bar"} - err = k8sClient.Create(ctx, sn) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, sn)).To(Succeed()) Expect(controllerutil.ContainsFinalizer(sn, constants.Finalizer)).To(BeTrue()) // deleting finalizer should succeed sn.Finalizers = nil - err = k8sClient.Update(ctx, sn) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Update(ctx, sn)).To(Succeed()) sn = &accuratev1.SubNamespace{} - err = k8sClient.Get(ctx, client.ObjectKey{Namespace: "ns2", Name: "foo"}, sn) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Get(ctx, client.ObjectKey{Namespace: "ns2", Name: "foo"}, sn)).To(Succeed()) Expect(sn.Finalizers).To(BeEmpty()) }) @@ -64,20 +59,17 @@ var _ = Describe("SubNamespace webhook", func() { nsP := &corev1.Namespace{} nsP.Name = "ns-parent" nsP.Labels = map[string]string{constants.LabelType: constants.NSTypeRoot} - err := k8sClient.Create(ctx, nsP) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, nsP)).To(Succeed()) ns := &corev1.Namespace{} ns.Name = "ns3" ns.Labels = map[string]string{constants.LabelParent: "ns-parent"} - err = k8sClient.Create(ctx, ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, ns)).To(Succeed()) sn := &accuratev1.SubNamespace{} sn.Namespace = "ns3" sn.Name = "bar" - err = k8sClient.Create(ctx, sn) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, sn)).To(Succeed()) Expect(controllerutil.ContainsFinalizer(sn, constants.Finalizer)).To(BeTrue()) }) @@ -89,90 +81,77 @@ var _ = Describe("SubNamespace webhook", func() { ns := &corev1.Namespace{} ns.Name = "naming-policy-root-1" ns.Labels = map[string]string{constants.LabelType: constants.NSTypeRoot} - err := k8sClient.Create(ctx, ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, ns)).To(Succeed()) sn := &accuratev1.SubNamespace{} sn.Namespace = "naming-policy-root-1" sn.Name = "naming-policy-root-1-child" - err = k8sClient.Create(ctx, sn) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, sn)).To(Succeed()) }) It("should allow creation of SubNamespace in a root namespace - pattern2", func() { ns := &corev1.Namespace{} ns.Name = "root-ns-match-1" ns.Labels = map[string]string{constants.LabelType: constants.NSTypeRoot} - err := k8sClient.Create(ctx, ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, ns)).To(Succeed()) sn := &accuratev1.SubNamespace{} sn.Namespace = "root-ns-match-1" sn.Name = "child-match-1" - err = k8sClient.Create(ctx, sn) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, sn)).To(Succeed()) }) It("should allow creation of SubNamespace in a root namespace - pattern3", func() { root := &corev1.Namespace{} root.Name = "ns-root-1" root.Labels = map[string]string{constants.LabelType: constants.NSTypeRoot} - err := k8sClient.Create(ctx, root) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, root)).To(Succeed()) parent := &corev1.Namespace{} parent.Name = "ns-root-1-parent" parent.Labels = map[string]string{constants.LabelParent: "ns-root-1"} - err = k8sClient.Create(ctx, parent) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, parent)).To(Succeed()) sn := &accuratev1.SubNamespace{} sn.Namespace = "ns-root-1-parent" sn.Name = "ns-root-1-parent-child" - err = k8sClient.Create(ctx, sn) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, sn)).To(Succeed()) }) It("should allow creation of SubNamespace in a root namespace - pattern4", func() { root := &corev1.Namespace{} root.Name = "app-team1" root.Labels = map[string]string{constants.LabelType: constants.NSTypeRoot} - err := k8sClient.Create(ctx, root) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, root)).To(Succeed()) sn := &accuratev1.SubNamespace{} sn.Namespace = "app-team1" sn.Name = "app-team1-child" - err = k8sClient.Create(ctx, sn) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, sn)).To(Succeed()) }) It("should allow creation of SubNamespace in a root namespace - pattern5", func() { root := &corev1.Namespace{} root.Name = "app-team2-app1" root.Labels = map[string]string{constants.LabelType: constants.NSTypeRoot} - err := k8sClient.Create(ctx, root) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, root)).To(Succeed()) sn := &accuratev1.SubNamespace{} sn.Namespace = "app-team2-app1" sn.Name = "app-team2-app1-subapp1" - err = k8sClient.Create(ctx, sn) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, sn)).To(Succeed()) }) It("should allow creation of SubNamespace in a root namespace - pattern6", func() { root := &corev1.Namespace{} root.Name = "unuse-naming-group-team1" root.Labels = map[string]string{constants.LabelType: constants.NSTypeRoot} - err := k8sClient.Create(ctx, root) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, root)).To(Succeed()) sn := &accuratev1.SubNamespace{} sn.Namespace = "unuse-naming-group-team1" sn.Name = "unuse-naming-group-child1" - err = k8sClient.Create(ctx, sn) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, sn)).To(Succeed()) }) }) @@ -181,13 +160,12 @@ var _ = Describe("SubNamespace webhook", func() { ns := &corev1.Namespace{} ns.Name = "naming-policy-root-2" ns.Labels = map[string]string{constants.LabelType: constants.NSTypeRoot} - err := k8sClient.Create(ctx, ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, ns)).To(Succeed()) sn := &accuratev1.SubNamespace{} sn.Namespace = "naming-policy-root-2" sn.Name = "naming-policy-root-2--child" - err = k8sClient.Create(ctx, sn) + err := k8sClient.Create(ctx, sn) Expect(err).To(HaveOccurred()) Expect(errors.ReasonForError(err)).Should(Equal(metav1.StatusReasonForbidden)) }) @@ -196,13 +174,12 @@ var _ = Describe("SubNamespace webhook", func() { ns := &corev1.Namespace{} ns.Name = "root-ns-match-2" ns.Labels = map[string]string{constants.LabelType: constants.NSTypeRoot} - err := k8sClient.Create(ctx, ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, ns)).To(Succeed()) sn := &accuratev1.SubNamespace{} sn.Namespace = "root-ns-match-2" sn.Name = "child-2" - err = k8sClient.Create(ctx, sn) + err := k8sClient.Create(ctx, sn) Expect(err).To(HaveOccurred()) Expect(errors.ReasonForError(err)).Should(Equal(metav1.StatusReasonForbidden)) }) @@ -211,19 +188,17 @@ var _ = Describe("SubNamespace webhook", func() { root := &corev1.Namespace{} root.Name = "ns-root-2" root.Labels = map[string]string{constants.LabelType: constants.NSTypeRoot} - err := k8sClient.Create(ctx, root) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, root)).To(Succeed()) parent := &corev1.Namespace{} parent.Name = "ns-root-2-parent" parent.Labels = map[string]string{constants.LabelParent: "ns-root-1"} - err = k8sClient.Create(ctx, parent) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, parent)).To(Succeed()) sn := &accuratev1.SubNamespace{} sn.Namespace = "ns-root-2-parent" sn.Name = "not-ns-root-2-parent-child" - err = k8sClient.Create(ctx, sn) + err := k8sClient.Create(ctx, sn) Expect(err).To(HaveOccurred()) Expect(errors.ReasonForError(err)).Should(Equal(metav1.StatusReasonForbidden)) }) @@ -232,13 +207,12 @@ var _ = Describe("SubNamespace webhook", func() { root := &corev1.Namespace{} root.Name = "app-team10" root.Labels = map[string]string{constants.LabelType: constants.NSTypeRoot} - err := k8sClient.Create(ctx, root) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, root)).To(Succeed()) sn := &accuratev1.SubNamespace{} sn.Namespace = "app-team10" sn.Name = "app-team20-child" - err = k8sClient.Create(ctx, sn) + err := k8sClient.Create(ctx, sn) Expect(err).To(HaveOccurred()) Expect(errors.ReasonForError(err)).Should(Equal(metav1.StatusReasonForbidden)) }) @@ -247,13 +221,12 @@ var _ = Describe("SubNamespace webhook", func() { root := &corev1.Namespace{} root.Name = "unuse-naming-group-team2" root.Labels = map[string]string{constants.LabelType: constants.NSTypeRoot} - err := k8sClient.Create(ctx, root) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, root)).To(Succeed()) sn := &accuratev1.SubNamespace{} sn.Namespace = "unuse-naming-group-team2" sn.Name = "unuse-naming-group-team2-foo" - err = k8sClient.Create(ctx, sn) + err := k8sClient.Create(ctx, sn) Expect(err).To(HaveOccurred()) Expect(errors.ReasonForError(err)).Should(Equal(metav1.StatusReasonForbidden)) }) @@ -262,14 +235,13 @@ var _ = Describe("SubNamespace webhook", func() { root := &corev1.Namespace{} root.Name = "labels-invalid-1" root.Labels = map[string]string{constants.LabelType: constants.NSTypeRoot} - err := k8sClient.Create(ctx, root) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, root)).To(Succeed()) sn := &accuratev1.SubNamespace{} sn.Namespace = "labels-invalid-1" sn.Name = "labels-invalid-1-sub" sn.Spec.Labels = map[string]string{"foo": "~"} - err = k8sClient.Create(ctx, sn) + err := k8sClient.Create(ctx, sn) Expect(err).To(HaveOccurred()) Expect(errors.ReasonForError(err)).Should(Equal(metav1.StatusReasonForbidden)) }) @@ -278,14 +250,13 @@ var _ = Describe("SubNamespace webhook", func() { root := &corev1.Namespace{} root.Name = "annotations-invalid-1" root.Labels = map[string]string{constants.LabelType: constants.NSTypeRoot} - err := k8sClient.Create(ctx, root) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, root)).To(Succeed()) sn := &accuratev1.SubNamespace{} sn.Namespace = "annotations-invalid-1" sn.Name = "annotations-invalid-1-sub" sn.Spec.Annotations = map[string]string{"foo-": ""} - err = k8sClient.Create(ctx, sn) + err := k8sClient.Create(ctx, sn) Expect(err).To(HaveOccurred()) Expect(errors.ReasonForError(err)).Should(Equal(metav1.StatusReasonForbidden)) }) @@ -294,15 +265,14 @@ var _ = Describe("SubNamespace webhook", func() { root := &corev1.Namespace{} root.Name = "both-invalid-1" root.Labels = map[string]string{constants.LabelType: constants.NSTypeRoot} - err := k8sClient.Create(ctx, root) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, root)).To(Succeed()) sn := &accuratev1.SubNamespace{} sn.Namespace = "both-invalid-1" sn.Name = "both-invalid-1-sub" sn.Spec.Labels = map[string]string{"foo": "~"} sn.Spec.Annotations = map[string]string{"foo-": ""} - err = k8sClient.Create(ctx, sn) + err := k8sClient.Create(ctx, sn) Expect(err).To(HaveOccurred()) Expect(errors.ReasonForError(err)).Should(Equal(metav1.StatusReasonForbidden)) }) diff --git a/hooks/subnamespace_v2_test.go b/hooks/subnamespace_v2_test.go index 2c1bf9d..3f69441 100644 --- a/hooks/subnamespace_v2_test.go +++ b/hooks/subnamespace_v2_test.go @@ -22,13 +22,12 @@ var _ = Describe("SubNamespace webhook", func() { It("should deny creation of v2 SubNamespace in a namespace that is neither root nor subnamespace", func() { ns := &corev1.Namespace{} ns.Name = "v2alpha1-ns1" - err := k8sClient.Create(ctx, ns) - Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient.Create(ctx, ns)).To(Succeed()) sn := &accuratev2alpha1.SubNamespace{} sn.Namespace = "v2alpha1-ns1" sn.Name = "v2alpha1-foo" - err = k8sClient.Create(ctx, sn) + err := k8sClient.Create(ctx, sn) Expect(err).To(HaveOccurred()) Expect(errors.ReasonForError(err)).Should(Equal(metav1.StatusReasonForbidden)) }) @@ -37,27 +36,23 @@ var _ = Describe("SubNamespace webhook", func() { ns := &corev1.Namespace{} ns.Name = "v2alpha1-ns2" ns.Labels = map[string]string{constants.LabelType: constants.NSTypeRoot} - err := k8sClient.Create(ctx, ns) - Expect(err).To(Succeed()) + Expect(k8sClient.Create(ctx, ns)).To(Succeed()) sn := &accuratev2alpha1.SubNamespace{} sn.Namespace = "v2alpha1-ns2" sn.Name = "v2alpha1-foo" sn.Spec.Labels = map[string]string{"foo": "bar"} sn.Spec.Annotations = map[string]string{"foo": "bar"} - err = k8sClient.Create(ctx, sn) - Expect(err).To(Succeed()) + Expect(k8sClient.Create(ctx, sn)).To(Succeed()) Expect(controllerutil.ContainsFinalizer(sn, constants.Finalizer)).To(BeTrue()) // deleting finalizer should succeed sn.Finalizers = nil - err = k8sClient.Update(ctx, sn) - Expect(err).To(Succeed()) + Expect(k8sClient.Update(ctx, sn)).To(Succeed()) sn = &accuratev2alpha1.SubNamespace{} - err = k8sClient.Get(ctx, client.ObjectKey{Namespace: "v2alpha1-ns2", Name: "v2alpha1-foo"}, sn) - Expect(err).To(Succeed()) + Expect(k8sClient.Get(ctx, client.ObjectKey{Namespace: "v2alpha1-ns2", Name: "v2alpha1-foo"}, sn)).To(Succeed()) Expect(sn.Finalizers).To(BeEmpty()) })