diff --git a/e2e/namespace_user_metadata_test.go b/e2e/namespace_user_metadata_test.go index 2abcea68..55243f79 100644 --- a/e2e/namespace_user_metadata_test.go +++ b/e2e/namespace_user_metadata_test.go @@ -7,11 +7,15 @@ package e2e import ( "context" + "time" - capsulev1beta1 "github.com/clastix/capsule/api/v1beta1" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + rbacv1 "k8s.io/api/rbac/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + + capsulev1beta1 "github.com/clastix/capsule/api/v1beta1" ) var _ = Describe("creating a Namespace with user-specified labels and annotations", func() { @@ -58,7 +62,7 @@ var _ = Describe("creating a Namespace with user-specified labels and annotation }) }) - It("should fail", func() { + It("should fail when creating a Namespace", func() { By("specifying forbidden labels using exact match", func() { ns := NewNamespace("namespace-user-metadata-forbidden-labels") ns.SetLabels(map[string]string{"foo": "bar"}) @@ -80,4 +84,118 @@ var _ = Describe("creating a Namespace with user-specified labels and annotation NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).ShouldNot(Succeed()) }) }) + + It("should fail when updating a Namespace", func() { + role := &rbacv1.Role{ + ObjectMeta: metav1.ObjectMeta{ + Name: "ns-patch", + }, + Rules: []rbacv1.PolicyRule{ + { + Verbs: []string{"patch", "update"}, + APIGroups: []string{""}, + Resources: []string{"namespaces"}, + }, + }, + } + + roleBinding := &rbacv1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "ns-patch", + }, + Subjects: []rbacv1.Subject{ + { + APIGroup: "rbac.authorization.k8s.io", + Kind: tnt.Spec.Owners[0].Kind.String(), + Name: tnt.Spec.Owners[0].Name, + }, + }, + RoleRef: rbacv1.RoleRef{ + APIGroup: "rbac.authorization.k8s.io", + Kind: "Role", + Name: role.GetName(), + }, + } + + rbacPatch := func(ns string) { + role := role.DeepCopy() + role.SetNamespace(ns) + Expect(k8sClient.Create(context.Background(), role)).To(Succeed()) + + roleBinding := roleBinding.DeepCopy() + roleBinding.SetNamespace(ns) + Expect(k8sClient.Create(context.Background(), roleBinding)).To(Succeed()) + } + + cs := ownerClient(tnt.Spec.Owners[0]) + + By("specifying forbidden labels using exact match", func() { + ns := NewNamespace("forbidden-labels-exact-match") + + NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed()) + rbacPatch(ns.GetName()) + Consistently(func() error { + if err := k8sClient.Get(context.Background(), types.NamespacedName{Name: ns.GetName()}, ns); err != nil { + return nil + } + + ns.SetLabels(map[string]string{"foo": "bar"}) + + _, err := cs.CoreV1().Namespaces().Update(context.Background(), ns, metav1.UpdateOptions{}) + + return err + }, 10*time.Second, time.Second).ShouldNot(Succeed()) + }) + By("specifying forbidden labels using regex match", func() { + ns := NewNamespace("forbidden-labels-regex-match") + + NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed()) + rbacPatch(ns.GetName()) + Consistently(func() error { + if err := k8sClient.Get(context.Background(), types.NamespacedName{Name: ns.GetName()}, ns); err != nil { + return nil + } + + ns.SetLabels(map[string]string{"gatsby-foo": "bar"}) + + _, err := cs.CoreV1().Namespaces().Update(context.Background(), ns, metav1.UpdateOptions{}) + + return err + }, 3*time.Second, time.Second).ShouldNot(Succeed()) + }) + By("specifying forbidden annotations using exact match", func() { + ns := NewNamespace("forbidden-annotations-exact-match") + + NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed()) + rbacPatch(ns.GetName()) + Consistently(func() error { + if err := k8sClient.Get(context.Background(), types.NamespacedName{Name: ns.GetName()}, ns); err != nil { + return nil + } + + ns.SetAnnotations(map[string]string{"foo": "bar"}) + + _, err := cs.CoreV1().Namespaces().Update(context.Background(), ns, metav1.UpdateOptions{}) + + return err + }, 10*time.Second, time.Second).ShouldNot(Succeed()) + }) + By("specifying forbidden annotations using regex match", func() { + ns := NewNamespace("forbidden-annotations-regex-match") + + NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed()) + rbacPatch(ns.GetName()) + Consistently(func() error { + if err := k8sClient.Get(context.Background(), types.NamespacedName{Name: ns.GetName()}, ns); err != nil { + return nil + } + + ns.SetAnnotations(map[string]string{"gatsby-foo": "bar"}) + + _, err := cs.CoreV1().Namespaces().Update(context.Background(), ns, metav1.UpdateOptions{}) + + return err + }, 10*time.Second, time.Second).ShouldNot(Succeed()) + }) + }) })