test(e2e): support multiple tenant owners(add applications to act as tenant owners)

This commit is contained in:
Maksim Fedotov
2021-07-08 11:39:29 +03:00
committed by Dario Tranchitella
parent 663ce93a3e
commit db8b8ac1d9
36 changed files with 360 additions and 295 deletions

View File

@@ -23,9 +23,11 @@ var _ = Describe("creating a Namespace with an additional Role Binding", func()
Name: "additional-role-binding",
},
Spec: capsulev1beta1.TenantSpec{
Owner: capsulev1beta1.OwnerSpec{
Name: "dale",
Kind: "User",
Owners: []capsulev1beta1.OwnerSpec{
{
Name: "dale",
Kind: "User",
},
},
AdditionalRoleBindings: []capsulev1beta1.AdditionalRoleBindingsSpec{
{
@@ -55,13 +57,13 @@ var _ = Describe("creating a Namespace with an additional Role Binding", func()
It("should be assigned to each Namespace", func() {
for _, ns := range []string{"rb-1", "rb-2", "rb-3"} {
ns := NewNamespace(ns)
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, defaultTimeoutInterval).Should(ContainElement(ns.GetName()))
var rb *rbacv1.RoleBinding
Eventually(func() (err error) {
cs := ownerClient(tnt)
cs := ownerClient(tnt.Spec.Owners[0])
rb, err = cs.RbacV1().RoleBindings(ns.Name).Get(context.Background(), fmt.Sprintf("capsule-%s-0-%s", tnt.Name, "crds-rolebinding"), metav1.GetOptions{})
return err
}, defaultTimeoutInterval, defaultPollInterval).Should(Succeed())

View File

@@ -23,9 +23,11 @@ var _ = Describe("enforcing an allowed set of Service external IPs", func() {
Name: "allowed-external-ip",
},
Spec: capsulev1beta1.TenantSpec{
Owner: capsulev1beta1.OwnerSpec{
Name: "google",
Kind: "User",
Owners: []capsulev1beta1.OwnerSpec{
{
Name: "google",
Kind: "User",
},
},
ExternalServiceIPs: &capsulev1beta1.ExternalServiceIPsSpec{
Allowed: []capsulev1beta1.AllowedIP{
@@ -48,7 +50,7 @@ var _ = Describe("enforcing an allowed set of Service external IPs", func() {
It("should fail creating an evil service", func() {
ns := NewNamespace("evil-service")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
svc := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
@@ -73,7 +75,7 @@ var _ = Describe("enforcing an allowed set of Service external IPs", func() {
},
}
EventuallyCreation(func() error {
cs := ownerClient(tnt)
cs := ownerClient(tnt.Spec.Owners[0])
_, err := cs.CoreV1().Services(ns.Name).Create(context.Background(), svc, metav1.CreateOptions{})
return err
}).ShouldNot(Succeed())
@@ -81,7 +83,7 @@ var _ = Describe("enforcing an allowed set of Service external IPs", func() {
It("should allow the first CIDR block", func() {
ns := NewNamespace("allowed-service-cidr")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
svc := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
@@ -106,7 +108,7 @@ var _ = Describe("enforcing an allowed set of Service external IPs", func() {
},
}
EventuallyCreation(func() error {
cs := ownerClient(tnt)
cs := ownerClient(tnt.Spec.Owners[0])
_, err := cs.CoreV1().Services(ns.Name).Create(context.Background(), svc, metav1.CreateOptions{})
return err
}).Should(Succeed())
@@ -114,7 +116,7 @@ var _ = Describe("enforcing an allowed set of Service external IPs", func() {
It("should allow the /32 CIDR block", func() {
ns := NewNamespace("allowed-service-strict")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
svc := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
@@ -138,7 +140,7 @@ var _ = Describe("enforcing an allowed set of Service external IPs", func() {
},
}
EventuallyCreation(func() error {
cs := ownerClient(tnt)
cs := ownerClient(tnt.Spec.Owners[0])
_, err := cs.CoreV1().Services(ns.Name).Create(context.Background(), svc, metav1.CreateOptions{})
return err
}).Should(Succeed())

View File

@@ -23,9 +23,11 @@ var _ = Describe("enforcing a Container Registry", func() {
Name: "container-registry",
},
Spec: capsulev1beta1.TenantSpec{
Owner: capsulev1beta1.OwnerSpec{
Name: "matt",
Kind: "User",
Owners: []capsulev1beta1.OwnerSpec{
{
Name: "matt",
Kind: "User",
},
},
ContainerRegistries: &capsulev1beta1.AllowedListSpec{
Exact: []string{"docker.io", "docker.tld"},
@@ -46,7 +48,7 @@ var _ = Describe("enforcing a Container Registry", func() {
It("should add labels to Namespace", func() {
ns := NewNamespace("registry-labels")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
Eventually(func() (ok bool) {
Expect(k8sClient.Get(context.Background(), types.NamespacedName{Name: ns.Name}, ns)).Should(Succeed())
ok, _ = HaveKeyWithValue("capsule.clastix.io/allowed-registries", "docker.io,docker.tld").Match(ns.Annotations)
@@ -63,7 +65,7 @@ var _ = Describe("enforcing a Container Registry", func() {
It("should deny running a gcr.io container", func() {
ns := NewNamespace("registry-deny")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
pod := &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
@@ -78,14 +80,14 @@ var _ = Describe("enforcing a Container Registry", func() {
},
},
}
cs := ownerClient(tnt)
cs := ownerClient(tnt.Spec.Owners[0])
_, err := cs.CoreV1().Pods(ns.Name).Create(context.Background(), pod, metav1.CreateOptions{})
Expect(err).ShouldNot(Succeed())
})
It("should allow using an exact match", func() {
ns := NewNamespace("registry-list")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
pod := &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
@@ -101,7 +103,7 @@ var _ = Describe("enforcing a Container Registry", func() {
},
}
cs := ownerClient(tnt)
cs := ownerClient(tnt.Spec.Owners[0])
EventuallyCreation(func() error {
_, err := cs.CoreV1().Pods(ns.Name).Create(context.Background(), pod, metav1.CreateOptions{})
return err
@@ -110,7 +112,7 @@ var _ = Describe("enforcing a Container Registry", func() {
It("should allow using a regex match", func() {
ns := NewNamespace("registry-regex")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
pod := &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
@@ -126,7 +128,7 @@ var _ = Describe("enforcing a Container Registry", func() {
},
}
cs := ownerClient(tnt)
cs := ownerClient(tnt.Spec.Owners[0])
EventuallyCreation(func() error {
_, err := cs.CoreV1().Pods(ns.Name).Create(context.Background(), pod, metav1.CreateOptions{})
return err

View File

@@ -23,9 +23,11 @@ var _ = Describe("creating a Namespace as Tenant owner with custom --capsule-gro
Name: "tenant-assigned-custom-group",
},
Spec: capsulev1beta1.TenantSpec{
Owner: capsulev1beta1.OwnerSpec{
Name: "alice",
Kind: "User",
Owners: []capsulev1beta1.OwnerSpec{
{
Name: "alice",
Kind: "User",
},
},
},
}
@@ -46,7 +48,7 @@ var _ = Describe("creating a Namespace as Tenant owner with custom --capsule-gro
})
ns := NewNamespace("cg-namespace-fail")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).ShouldNot(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).ShouldNot(Succeed())
})
It("should succeed and be available in Tenant namespaces list with multiple groups", func() {
@@ -56,7 +58,7 @@ var _ = Describe("creating a Namespace as Tenant owner with custom --capsule-gro
ns := NewNamespace("cg-namespace-1")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, defaultTimeoutInterval).Should(ContainElement(ns.GetName()))
})
@@ -67,7 +69,7 @@ var _ = Describe("creating a Namespace as Tenant owner with custom --capsule-gro
ns := NewNamespace("cg-namespace-2")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, defaultTimeoutInterval).Should(ContainElement(ns.GetName()))
})
})

View File

@@ -23,9 +23,11 @@ var _ = Describe("creating a nodePort service when it is disabled for Tenant", f
Name: "disable-node-ports",
},
Spec: capsulev1beta1.TenantSpec{
Owner: capsulev1beta1.OwnerSpec{
Name: "google",
Kind: "User",
Owners: []capsulev1beta1.OwnerSpec{
{
Name: "google",
Kind: "User",
},
},
EnableNodePorts: false,
},
@@ -43,7 +45,7 @@ var _ = Describe("creating a nodePort service when it is disabled for Tenant", f
It("should fail creating a service with NodePort type", func() {
ns := NewNamespace("disable-node-ports")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
svc := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
@@ -65,7 +67,7 @@ var _ = Describe("creating a nodePort service when it is disabled for Tenant", f
},
}
EventuallyCreation(func() error {
cs := ownerClient(tnt)
cs := ownerClient(tnt.Spec.Owners[0])
_, err := cs.CoreV1().Services(ns.Name).Create(context.Background(), svc, metav1.CreateOptions{})
return err
}).ShouldNot(Succeed())

View File

@@ -23,9 +23,11 @@ var _ = Describe("creating a nodePort service when it is enabled for Tenant", fu
Name: "enable-node-ports",
},
Spec: capsulev1beta1.TenantSpec{
Owner: capsulev1beta1.OwnerSpec{
Name: "google",
Kind: "User",
Owners: []capsulev1beta1.OwnerSpec{
{
Name: "google",
Kind: "User",
},
},
},
}
@@ -42,7 +44,7 @@ var _ = Describe("creating a nodePort service when it is enabled for Tenant", fu
It("should allow creating a service with NodePort type", func() {
ns := NewNamespace("enable-node-ports")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
svc := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
@@ -64,7 +66,7 @@ var _ = Describe("creating a nodePort service when it is enabled for Tenant", fu
},
}
EventuallyCreation(func() error {
cs := ownerClient(tnt)
cs := ownerClient(tnt.Spec.Owners[0])
_, err := cs.CoreV1().Services(ns.Name).Create(context.Background(), svc, metav1.CreateOptions{})
return err
}).Should(Succeed())

View File

@@ -23,9 +23,11 @@ var _ = Describe("creating a Namespace with Tenant name prefix enforcement", fun
Name: "awesome",
},
Spec: capsulev1beta1.TenantSpec{
Owner: capsulev1beta1.OwnerSpec{
Name: "john",
Kind: "User",
Owners: []capsulev1beta1.OwnerSpec{
{
Name: "john",
Kind: "User",
},
},
},
}
@@ -34,9 +36,11 @@ var _ = Describe("creating a Namespace with Tenant name prefix enforcement", fun
Name: "awesome-tenant",
},
Spec: capsulev1beta1.TenantSpec{
Owner: capsulev1beta1.OwnerSpec{
Name: "john",
Kind: "User",
Owners: []capsulev1beta1.OwnerSpec{
{
Name: "john",
Kind: "User",
},
},
},
}
@@ -66,20 +70,20 @@ var _ = Describe("creating a Namespace with Tenant name prefix enforcement", fun
It("should fail when non using prefix", func() {
ns := NewNamespace("awesome")
NamespaceCreation(ns, t1, defaultTimeoutInterval).ShouldNot(Succeed())
NamespaceCreation(ns, t1.Spec.Owners[0], defaultTimeoutInterval).ShouldNot(Succeed())
})
It("should succeed using prefix", func() {
ns := NewNamespace("awesome-namespace")
NamespaceCreation(ns, t1, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, t1.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
})
It("should succeed and assigned according to closest match", func() {
ns1 := NewNamespace("awesome-tenant")
ns2 := NewNamespace("awesome-tenant-namespace")
NamespaceCreation(ns1, t1, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns2, t2, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns1, t1.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns2, t2.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(t1, defaultTimeoutInterval).Should(ContainElement(ns1.GetName()))
TenantNamespaceList(t2, defaultTimeoutInterval).Should(ContainElement(ns2.GetName()))

View File

@@ -22,9 +22,11 @@ var _ = Describe("enforcing some defined ImagePullPolicy", func() {
Name: "image-pull-policies",
},
Spec: capsulev1beta1.TenantSpec{
Owner: capsulev1beta1.OwnerSpec{
Name: "alex",
Kind: "User",
Owners: []capsulev1beta1.OwnerSpec{
{
Name: "alex",
Kind: "User",
},
},
ImagePullPolicies: []capsulev1beta1.ImagePullPolicySpec{"Always", "IfNotPresent"},
},
@@ -43,9 +45,9 @@ var _ = Describe("enforcing some defined ImagePullPolicy", func() {
It("should just allow the defined policies", func() {
ns := NewNamespace("allow-policy")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
cs := ownerClient(tnt)
cs := ownerClient(tnt.Spec.Owners[0])
By("allowing Always", func() {
pod := &corev1.Pod{

View File

@@ -22,9 +22,11 @@ var _ = Describe("enforcing a defined ImagePullPolicy", func() {
Name: "image-pull-policy",
},
Spec: capsulev1beta1.TenantSpec{
Owner: capsulev1beta1.OwnerSpec{
Name: "axel",
Kind: "User",
Owners: []capsulev1beta1.OwnerSpec{
{
Name: "axel",
Kind: "User",
},
},
ImagePullPolicies: []capsulev1beta1.ImagePullPolicySpec{"Always"},
},
@@ -43,9 +45,9 @@ var _ = Describe("enforcing a defined ImagePullPolicy", func() {
It("should just allow the defined policy", func() {
ns := NewNamespace("allow-policies")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
cs := ownerClient(tnt)
cs := ownerClient(tnt.Spec.Owners[0])
By("allowing Always", func() {
pod := &corev1.Pod{

View File

@@ -24,9 +24,11 @@ var _ = Describe("when Tenant handles Ingress classes", func() {
Name: "ingress-class",
},
Spec: capsulev1beta1.TenantSpec{
Owner: capsulev1beta1.OwnerSpec{
Name: "ingress",
Kind: "User",
Owners: []capsulev1beta1.OwnerSpec{
{
Name: "ingress",
Kind: "User",
},
},
IngressClasses: &capsulev1beta1.AllowedListSpec{
Exact: []string{
@@ -50,9 +52,9 @@ var _ = Describe("when Tenant handles Ingress classes", func() {
It("should block a non allowed class", func() {
ns := NewNamespace("ingress-class-disallowed")
cs := ownerClient(tnt)
cs := ownerClient(tnt.Spec.Owners[0])
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, defaultTimeoutInterval).Should(ContainElement(ns.GetName()))
By("non-specifying at all", func() {
@@ -114,9 +116,9 @@ var _ = Describe("when Tenant handles Ingress classes", func() {
It("should allow enabled class using the deprecated annotation", func() {
ns := NewNamespace("ingress-class-allowed-annotation")
cs := ownerClient(tnt)
cs := ownerClient(tnt.Spec.Owners[0])
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, defaultTimeoutInterval).Should(ContainElement(ns.GetName()))
for _, c := range tnt.Spec.IngressClasses.Exact {
@@ -143,14 +145,14 @@ var _ = Describe("when Tenant handles Ingress classes", func() {
It("should allow enabled class using the ingressClassName field", func() {
ns := NewNamespace("ingress-class-allowed-annotation")
cs := ownerClient(tnt)
cs := ownerClient(tnt.Spec.Owners[0])
maj, min, v := GetKubernetesSemVer()
if maj == 1 && min < 18 {
Skip("Running test on Kubernetes " + v + ", doesn't provide .spec.ingressClassName")
}
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, defaultTimeoutInterval).Should(ContainElement(ns.GetName()))
for _, c := range tnt.Spec.IngressClasses.Exact {
@@ -175,10 +177,10 @@ var _ = Describe("when Tenant handles Ingress classes", func() {
It("should allow enabled Ingress by regex using the deprecated annotation", func() {
ns := NewNamespace("ingress-class-allowed-annotation")
cs := ownerClient(tnt)
cs := ownerClient(tnt.Spec.Owners[0])
ingressClass := "oil-ingress"
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, defaultTimeoutInterval).Should(ContainElement(ns.GetName()))
Eventually(func() (err error) {
@@ -203,7 +205,7 @@ var _ = Describe("when Tenant handles Ingress classes", func() {
It("should allow enabled Ingress by regex using the ingressClassName field", func() {
ns := NewNamespace("ingress-class-allowed-annotation")
cs := ownerClient(tnt)
cs := ownerClient(tnt.Spec.Owners[0])
ingressClass := "oil-haproxy"
maj, min, v := GetKubernetesSemVer()
@@ -211,7 +213,7 @@ var _ = Describe("when Tenant handles Ingress classes", func() {
Skip("Running test on Kubernetes " + v + ", doesn't provide .spec.ingressClassName")
}
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, defaultTimeoutInterval).Should(ContainElement(ns.GetName()))
Eventually(func() (err error) {

View File

@@ -25,9 +25,11 @@ var _ = Describe("when handling Ingress hostnames collision", func() {
Name: "ingress-hostnames-allowed-collision",
},
Spec: capsulev1beta1.TenantSpec{
Owner: capsulev1beta1.OwnerSpec{
Name: "ingress-allowed",
Kind: "User",
Owners: []capsulev1beta1.OwnerSpec{
{
Name: "ingress-allowed",
Kind: "User",
},
},
},
}
@@ -91,9 +93,9 @@ var _ = Describe("when handling Ingress hostnames collision", func() {
maj, min, _ := GetKubernetesSemVer()
ns := NewNamespace("denied-collision")
cs := ownerClient(tnt)
cs := ownerClient(tnt.Spec.Owners[0])
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, defaultTimeoutInterval).Should(ContainElement(ns.GetName()))
if maj == 1 && min > 18 {
@@ -132,9 +134,9 @@ var _ = Describe("when handling Ingress hostnames collision", func() {
maj, min, _ := GetKubernetesSemVer()
ns := NewNamespace("allowed-collision")
cs := ownerClient(tnt)
cs := ownerClient(tnt.Spec.Owners[0])
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, defaultTimeoutInterval).Should(ContainElement(ns.GetName()))
if maj == 1 && min > 18 {

View File

@@ -25,9 +25,11 @@ var _ = Describe("when handling Ingress hostnames collision", func() {
Name: "ingress-hostnames-denied-collision",
},
Spec: capsulev1beta1.TenantSpec{
Owner: capsulev1beta1.OwnerSpec{
Name: "ingress-denied",
Kind: "User",
Owners: []capsulev1beta1.OwnerSpec{
{
Name: "ingress-denied",
Kind: "User",
},
},
},
}
@@ -85,9 +87,9 @@ var _ = Describe("when handling Ingress hostnames collision", func() {
maj, min, _ := GetKubernetesSemVer()
ns := NewNamespace("allowed-collision")
cs := ownerClient(tnt)
cs := ownerClient(tnt.Spec.Owners[0])
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, defaultTimeoutInterval).Should(ContainElement(ns.GetName()))
if maj == 1 && min > 18 {

View File

@@ -25,9 +25,11 @@ var _ = Describe("when Tenant handles Ingress hostnames", func() {
Name: "ingress-hostnames",
},
Spec: capsulev1beta1.TenantSpec{
Owner: capsulev1beta1.OwnerSpec{
Name: "hostname",
Kind: "User",
Owners: []capsulev1beta1.OwnerSpec{
{
Name: "hostname",
Kind: "User",
},
},
IngressHostnames: &capsulev1beta1.AllowedListSpec{
Exact: []string{"sigs.k8s.io", "operator.sdk", "domain.tld"},
@@ -118,9 +120,9 @@ var _ = Describe("when Tenant handles Ingress hostnames", func() {
if maj == 1 && min > 18 {
ns := NewNamespace("disallowed-hostname-networking")
cs := ownerClient(tnt)
cs := ownerClient(tnt.Spec.Owners[0])
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, defaultTimeoutInterval).Should(ContainElement(ns.GetName()))
By("testing networking.k8s.io", func() {
@@ -143,9 +145,9 @@ var _ = Describe("when Tenant handles Ingress hostnames", func() {
if maj == 1 && min < 22 {
By("testing extensions", func() {
ns := NewNamespace("disallowed-hostname-extensions")
cs := ownerClient(tnt)
cs := ownerClient(tnt.Spec.Owners[0])
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, defaultTimeoutInterval).Should(ContainElement(ns.GetName()))
Eventually(func() (err error) {
@@ -166,9 +168,9 @@ var _ = Describe("when Tenant handles Ingress hostnames", func() {
if maj == 1 && min > 18 {
ns := NewNamespace("allowed-hostname-list-networking")
cs := ownerClient(tnt)
cs := ownerClient(tnt.Spec.Owners[0])
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, defaultTimeoutInterval).Should(ContainElement(ns.GetName()))
By("testing networking.k8s.io", func() {
@@ -192,9 +194,9 @@ var _ = Describe("when Tenant handles Ingress hostnames", func() {
if maj == 1 && min < 22 {
ns := NewNamespace("allowed-hostname-list-extensions")
cs := ownerClient(tnt)
cs := ownerClient(tnt.Spec.Owners[0])
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, defaultTimeoutInterval).Should(ContainElement(ns.GetName()))
By("testing extensions", func() {
@@ -218,9 +220,9 @@ var _ = Describe("when Tenant handles Ingress hostnames", func() {
if maj == 1 && min > 18 {
ns := NewNamespace("allowed-hostname-regex-networking")
cs := ownerClient(tnt)
cs := ownerClient(tnt.Spec.Owners[0])
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, defaultTimeoutInterval).Should(ContainElement(ns.GetName()))
By("testing networking.k8s.io", func() {
@@ -245,9 +247,9 @@ var _ = Describe("when Tenant handles Ingress hostnames", func() {
if maj == 1 && min < 22 {
By("testing extensions", func() {
ns := NewNamespace("allowed-hostname-regex-extensions")
cs := ownerClient(tnt)
cs := ownerClient(tnt.Spec.Owners[0])
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, defaultTimeoutInterval).Should(ContainElement(ns.GetName()))
for _, h := range []string{"foo", "bar", "bizz"} {

View File

@@ -19,14 +19,16 @@ var _ = Describe("creating a Namespace creation with no Tenant assigned", func()
It("should fail", func() {
tnt := &capsulev1beta1.Tenant{
Spec: capsulev1beta1.TenantSpec{
Owner: capsulev1beta1.OwnerSpec{
Name: "missing",
Kind: "User",
Owners: []capsulev1beta1.OwnerSpec{
{
Name: "missing",
Kind: "User",
},
},
},
}
ns := NewNamespace("no-namespace")
cs := ownerClient(tnt)
cs := ownerClient(tnt.Spec.Owners[0])
_, err := cs.CoreV1().Namespaces().Create(context.TODO(), ns, metav1.CreateOptions{})
Expect(err).ShouldNot(Succeed())
})

View File

@@ -23,9 +23,11 @@ var _ = Describe("creating several Namespaces for a Tenant", func() {
Name: "capsule-labels",
},
Spec: capsulev1beta1.TenantSpec{
Owner: capsulev1beta1.OwnerSpec{
Name: "charlie",
Kind: "User",
Owners: []capsulev1beta1.OwnerSpec{
{
Name: "charlie",
Kind: "User",
},
},
},
}
@@ -47,7 +49,7 @@ var _ = Describe("creating several Namespaces for a Tenant", func() {
NewNamespace("third-capsule-ns"),
}
for _, ns := range namespaces {
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
Eventually(func() (ok bool) {
Expect(k8sClient.Get(context.TODO(), types.NamespacedName{Name: ns.GetName()}, ns)).Should(Succeed())
ok, _ = HaveKeyWithValue("capsule.clastix.io/tenant", tnt.Name).Match(ns.Labels)

View File

@@ -22,9 +22,11 @@ var _ = Describe("creating a Namespace for a Tenant with additional metadata", f
Name: "tenant-metadata",
},
Spec: capsulev1beta1.TenantSpec{
Owner: capsulev1beta1.OwnerSpec{
Name: "gatsby",
Kind: "User",
Owners: []capsulev1beta1.OwnerSpec{
{
Name: "gatsby",
Kind: "User",
},
},
NamespacesMetadata: &capsulev1beta1.AdditionalMetadataSpec{
AdditionalLabels: map[string]string{
@@ -50,7 +52,7 @@ var _ = Describe("creating a Namespace for a Tenant with additional metadata", f
It("should contain additional Namespace metadata", func() {
ns := NewNamespace("namespace-metadata")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, defaultTimeoutInterval).Should(ContainElement(ns.GetName()))
By("checking additional labels", func() {

View File

@@ -15,21 +15,32 @@ import (
capsulev1beta1 "github.com/clastix/capsule/api/v1beta1"
)
var _ = Describe("creating a Namespace as Tenant owner", func() {
var _ = Describe("creating a Namespaces as different type of Tenant owners", func() {
tnt := &capsulev1beta1.Tenant{
ObjectMeta: metav1.ObjectMeta{
Name: "tenant-assigned",
},
Spec: capsulev1beta1.TenantSpec{
Owner: capsulev1beta1.OwnerSpec{
Name: "alice",
Kind: "User",
Owners: []capsulev1beta1.OwnerSpec{
{
Name: "alice",
Kind: "User",
},
{
Name: "bob",
Kind: "Group",
},
{
Name: "system:serviceaccount:new-namespace-sa:default",
Kind: "ServiceAccount",
},
},
},
}
JustBeforeEach(func() {
EventuallyCreation(func() error {
tnt.ResourceVersion = ""
return k8sClient.Create(context.TODO(), tnt)
}).Should(Succeed())
})
@@ -37,9 +48,28 @@ var _ = Describe("creating a Namespace as Tenant owner", func() {
Expect(k8sClient.Delete(context.TODO(), tnt)).Should(Succeed())
})
It("should be available in Tenant namespaces list", func() {
ns := NewNamespace("new-namespace")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, defaultTimeoutInterval).Should(ContainElement(ns.GetName()))
It("should be available in Tenant namespaces list and rolebindigs should present when created as User", func() {
ns := NewNamespace("new-namespace-user")
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, defaultTimeoutInterval).Should(ContainElements(ns.GetName()))
for _, a := range KindInTenantRoleBindingAssertions(ns, defaultTimeoutInterval) {
a.Should(ContainElements("User", "Group", "ServiceAccount"))
}
})
It("should be available in Tenant namespaces list and rolebindigs should present when created as Group", func() {
ns := NewNamespace("new-namespace-group")
NamespaceCreation(ns, tnt.Spec.Owners[1], defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, defaultTimeoutInterval).Should(ContainElements(ns.GetName()))
for _, a := range KindInTenantRoleBindingAssertions(ns, defaultTimeoutInterval) {
a.Should(ContainElements("User", "Group", "ServiceAccount"))
}
})
It("should be available in Tenant namespaces list and rolebindigs should present when created as ServiceAccount", func() {
ns := NewNamespace("new-namespace-sa")
NamespaceCreation(ns, tnt.Spec.Owners[2], defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, defaultTimeoutInterval).Should(ContainElements(ns.GetName()))
for _, a := range KindInTenantRoleBindingAssertions(ns, defaultTimeoutInterval) {
a.Should(ContainElements("User", "Group", "ServiceAccount"))
}
})
})

View File

@@ -22,9 +22,11 @@ var _ = Describe("creating a Namespace in over-quota of three", func() {
Name: "over-quota-tenant",
},
Spec: capsulev1beta1.TenantSpec{
Owner: capsulev1beta1.OwnerSpec{
Name: "bob",
Kind: "User",
Owners: []capsulev1beta1.OwnerSpec{
{
Name: "bob",
Kind: "User",
},
},
NamespaceQuota: pointer.Int32Ptr(3),
},
@@ -43,13 +45,13 @@ var _ = Describe("creating a Namespace in over-quota of three", func() {
By("creating three Namespaces", func() {
for _, name := range []string{"bob-dev", "bob-staging", "bob-production"} {
ns := NewNamespace(name)
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, defaultTimeoutInterval).Should(ContainElement(ns.GetName()))
}
})
ns := NewNamespace("bob-fail")
cs := ownerClient(tnt)
cs := ownerClient(tnt.Spec.Owners[0])
_, err := cs.CoreV1().Namespaces().Create(context.TODO(), ns, metav1.CreateOptions{})
Expect(err).ShouldNot(Succeed())
})

View File

@@ -26,9 +26,11 @@ var _ = Describe("when Tenant owner interacts with the webhooks", func() {
Name: "tenant-owner",
},
Spec: capsulev1beta1.TenantSpec{
Owner: capsulev1beta1.OwnerSpec{
Name: "ruby",
Kind: "User",
Owners: []capsulev1beta1.OwnerSpec{
{
Name: "ruby",
Kind: "User",
},
},
StorageClasses: &capsulev1beta1.AllowedListSpec{
Exact: []string{
@@ -98,7 +100,7 @@ var _ = Describe("when Tenant owner interacts with the webhooks", func() {
It("should disallow deletions", func() {
By("blocking Capsule Limit ranges", func() {
ns := NewNamespace("limit-range-disallow")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, defaultTimeoutInterval).Should(ContainElement(ns.GetName()))
lr := &corev1.LimitRange{}
@@ -107,12 +109,12 @@ var _ = Describe("when Tenant owner interacts with the webhooks", func() {
return k8sClient.Get(context.TODO(), types.NamespacedName{Name: n, Namespace: ns.GetName()}, lr)
}, defaultTimeoutInterval, defaultPollInterval).Should(Succeed())
cs := ownerClient(tnt)
cs := ownerClient(tnt.Spec.Owners[0])
Expect(cs.CoreV1().LimitRanges(ns.GetName()).Delete(context.TODO(), lr.Name, metav1.DeleteOptions{})).ShouldNot(Succeed())
})
By("blocking Capsule Network Policy", func() {
ns := NewNamespace("network-policy-disallow")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, defaultTimeoutInterval).Should(ContainElement(ns.GetName()))
np := &networkingv1.NetworkPolicy{}
@@ -121,12 +123,12 @@ var _ = Describe("when Tenant owner interacts with the webhooks", func() {
return k8sClient.Get(context.TODO(), types.NamespacedName{Name: n, Namespace: ns.GetName()}, np)
}, defaultTimeoutInterval, defaultPollInterval).Should(Succeed())
cs := ownerClient(tnt)
cs := ownerClient(tnt.Spec.Owners[0])
Expect(cs.NetworkingV1().NetworkPolicies(ns.GetName()).Delete(context.TODO(), np.Name, metav1.DeleteOptions{})).ShouldNot(Succeed())
})
By("blocking Capsule Resource Quota", func() {
ns := NewNamespace("resource-quota-disallow")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, defaultTimeoutInterval).Should(ContainElement(ns.GetName()))
rq := &corev1.ResourceQuota{}
@@ -135,7 +137,7 @@ var _ = Describe("when Tenant owner interacts with the webhooks", func() {
return k8sClient.Get(context.TODO(), types.NamespacedName{Name: n, Namespace: ns.GetName()}, rq)
}, defaultTimeoutInterval, defaultPollInterval).Should(Succeed())
cs := ownerClient(tnt)
cs := ownerClient(tnt.Spec.Owners[0])
Expect(cs.NetworkingV1().NetworkPolicies(ns.GetName()).Delete(context.TODO(), rq.Name, metav1.DeleteOptions{})).ShouldNot(Succeed())
})
})
@@ -143,33 +145,33 @@ var _ = Describe("when Tenant owner interacts with the webhooks", func() {
It("should allow", func() {
By("listing Limit Range", func() {
ns := NewNamespace("limit-range-list")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, defaultTimeoutInterval).Should(ContainElement(ns.GetName()))
Eventually(func() (err error) {
cs := ownerClient(tnt)
cs := ownerClient(tnt.Spec.Owners[0])
_, err = cs.CoreV1().LimitRanges(ns.GetName()).List(context.TODO(), metav1.ListOptions{})
return
}, defaultTimeoutInterval, defaultPollInterval).Should(Succeed())
})
By("listing Network Policy", func() {
ns := NewNamespace("network-policy-list")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, defaultTimeoutInterval).Should(ContainElement(ns.GetName()))
Eventually(func() (err error) {
cs := ownerClient(tnt)
cs := ownerClient(tnt.Spec.Owners[0])
_, err = cs.NetworkingV1().NetworkPolicies(ns.GetName()).List(context.TODO(), metav1.ListOptions{})
return
}, defaultTimeoutInterval, defaultPollInterval).Should(Succeed())
})
By("listing Resource Quota", func() {
ns := NewNamespace("resource-quota-list")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, defaultTimeoutInterval).Should(ContainElement(ns.GetName()))
Eventually(func() (err error) {
cs := ownerClient(tnt)
cs := ownerClient(tnt.Spec.Owners[0])
_, err = cs.NetworkingV1().NetworkPolicies(ns.GetName()).List(context.TODO(), metav1.ListOptions{})
return
}, defaultTimeoutInterval, defaultPollInterval).Should(Succeed())
@@ -178,10 +180,10 @@ var _ = Describe("when Tenant owner interacts with the webhooks", func() {
It("should allow all actions to Tenant owner Network Policy", func() {
ns := NewNamespace("network-policy-allow")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, defaultTimeoutInterval).Should(ContainElement(ns.GetName()))
cs := ownerClient(tnt)
cs := ownerClient(tnt.Spec.Owners[0])
np := &networkingv1.NetworkPolicy{
ObjectMeta: metav1.ObjectMeta{
Name: "custom-network-policy",

View File

@@ -23,9 +23,11 @@ var _ = Describe("enforcing a Priority Class", func() {
Name: "priority-class",
},
Spec: capsulev1beta1.TenantSpec{
Owner: capsulev1beta1.OwnerSpec{
Name: "george",
Kind: "User",
Owners: []capsulev1beta1.OwnerSpec{
{
Name: "george",
Kind: "User",
},
},
PriorityClasses: &capsulev1beta1.AllowedListSpec{
Exact: []string{"gold"},
@@ -46,7 +48,7 @@ var _ = Describe("enforcing a Priority Class", func() {
It("should block non allowed Priority Class", func() {
ns := NewNamespace("system-node-critical")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
pod := &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
@@ -63,7 +65,7 @@ var _ = Describe("enforcing a Priority Class", func() {
},
}
cs := ownerClient(tnt)
cs := ownerClient(tnt.Spec.Owners[0])
EventuallyCreation(func() error {
_, err := cs.CoreV1().Pods(ns.GetName()).Create(context.Background(), pod, metav1.CreateOptions{})
return err
@@ -85,7 +87,7 @@ var _ = Describe("enforcing a Priority Class", func() {
}()
ns := NewNamespace("pc-exact-match")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
pod := &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
@@ -102,7 +104,7 @@ var _ = Describe("enforcing a Priority Class", func() {
},
}
cs := ownerClient(tnt)
cs := ownerClient(tnt.Spec.Owners[0])
EventuallyCreation(func() error {
_, err := cs.CoreV1().Pods(ns.GetName()).Create(context.Background(), pod, metav1.CreateOptions{})
return err
@@ -112,7 +114,7 @@ var _ = Describe("enforcing a Priority Class", func() {
It("should allow regex match", func() {
ns := NewNamespace("pc-regex-match")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
for i, pc := range []string{"pc-bronze", "pc-silver", "pc-gold"} {
class := &v1.PriorityClass{
@@ -140,7 +142,7 @@ var _ = Describe("enforcing a Priority Class", func() {
},
}
cs := ownerClient(tnt)
cs := ownerClient(tnt.Spec.Owners[0])
EventuallyCreation(func() error {
_, err := cs.CoreV1().Pods(ns.GetName()).Create(context.Background(), pod, metav1.CreateOptions{})

View File

@@ -23,9 +23,11 @@ var _ = Describe("creating a Namespace with a protected Namespace regex enabled"
Name: "tenant-protected-namespace",
},
Spec: capsulev1beta1.TenantSpec{
Owner: capsulev1beta1.OwnerSpec{
Name: "alice",
Kind: "User",
Owners: []capsulev1beta1.OwnerSpec{
{
Name: "alice",
Kind: "User",
},
},
},
}
@@ -47,13 +49,13 @@ var _ = Describe("creating a Namespace with a protected Namespace regex enabled"
ns := NewNamespace("test-ok")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, defaultTimeoutInterval).Should(ContainElement(ns.GetName()))
})
It("should fail using a value non matching the regex", func() {
ns := NewNamespace("test-system")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).ShouldNot(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).ShouldNot(Succeed())
ModifyCapsuleConfigurationOpts(func(configuration *capsulev1alpha1.CapsuleConfiguration) {
configuration.Spec.ProtectedNamespaceRegexpString = ""

View File

@@ -27,9 +27,11 @@ var _ = Describe("exceeding a Tenant resource quota", func() {
Name: "tenant-resources-changes",
},
Spec: capsulev1beta1.TenantSpec{
Owner: capsulev1beta1.OwnerSpec{
Name: "bobby",
Kind: "User",
Owners: []capsulev1beta1.OwnerSpec{
{
Name: "bobby",
Kind: "User",
},
},
LimitRanges: &capsulev1beta1.LimitRangesSpec{Items: []corev1.LimitRangeSpec{
{
@@ -113,7 +115,7 @@ var _ = Describe("exceeding a Tenant resource quota", func() {
By("creating the Namespaces", func() {
for _, i := range nsl {
ns := NewNamespace(i)
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, defaultTimeoutInterval).Should(ContainElement(ns.GetName()))
}
})
@@ -123,7 +125,7 @@ var _ = Describe("exceeding a Tenant resource quota", func() {
})
It("should block new Pods", func() {
cs := ownerClient(tnt)
cs := ownerClient(tnt.Spec.Owners[0])
for _, namespace := range nsl {
Eventually(func() (err error) {
d := &appsv1.Deployment{
@@ -186,7 +188,7 @@ var _ = Describe("exceeding a Tenant resource quota", func() {
},
},
}
cs := ownerClient(tnt)
cs := ownerClient(tnt.Spec.Owners[0])
EventuallyCreation(func() error {
_, err := cs.CoreV1().Pods(ns).Create(context.Background(), pod, metav1.CreateOptions{})
return err

View File

@@ -22,9 +22,11 @@ var _ = Describe("creating a Namespace trying to select a third Tenant", func()
Name: "tenant-non-owned",
},
Spec: capsulev1beta1.TenantSpec{
Owner: capsulev1beta1.OwnerSpec{
Name: "undefined",
Kind: "User",
Owners: []capsulev1beta1.OwnerSpec{
{
Name: "undefined",
Kind: "User",
},
},
},
}
@@ -51,7 +53,7 @@ var _ = Describe("creating a Namespace trying to select a third Tenant", func()
})
})
cs := ownerClient(&capsulev1beta1.Tenant{Spec: capsulev1beta1.TenantSpec{Owner: capsulev1beta1.OwnerSpec{Name: "dale", Kind: "User"}}})
cs := ownerClient(capsulev1beta1.OwnerSpec{Name: "dale", Kind: "User"})
_, err := cs.CoreV1().Namespaces().Create(context.TODO(), ns, metav1.CreateOptions{})
Expect(err).To(HaveOccurred())
})

View File

@@ -21,9 +21,11 @@ var _ = Describe("creating a Namespace without a Tenant selector when user owns
Name: "tenant-one",
},
Spec: capsulev1beta1.TenantSpec{
Owner: capsulev1beta1.OwnerSpec{
Name: "john",
Kind: "User",
Owners: []capsulev1beta1.OwnerSpec{
{
Name: "john",
Kind: "User",
},
},
},
}
@@ -32,9 +34,11 @@ var _ = Describe("creating a Namespace without a Tenant selector when user owns
Name: "tenant-two",
},
Spec: capsulev1beta1.TenantSpec{
Owner: capsulev1beta1.OwnerSpec{
Name: "john",
Kind: "User",
Owners: []capsulev1beta1.OwnerSpec{
{
Name: "john",
Kind: "User",
},
},
},
}
@@ -43,9 +47,11 @@ var _ = Describe("creating a Namespace without a Tenant selector when user owns
Name: "tenant-three",
},
Spec: capsulev1beta1.TenantSpec{
Owner: capsulev1beta1.OwnerSpec{
Name: "john",
Kind: "Group",
Owners: []capsulev1beta1.OwnerSpec{
{
Name: "john",
Kind: "Group",
},
},
},
}
@@ -54,9 +60,11 @@ var _ = Describe("creating a Namespace without a Tenant selector when user owns
Name: "tenant-four",
},
Spec: capsulev1beta1.TenantSpec{
Owner: capsulev1beta1.OwnerSpec{
Name: "john",
Kind: "Group",
Owners: []capsulev1beta1.OwnerSpec{
{
Name: "john",
Kind: "Group",
},
},
},
}
@@ -66,16 +74,16 @@ var _ = Describe("creating a Namespace without a Tenant selector when user owns
By("user owns 2 tenants", func() {
EventuallyCreation(func() error { return k8sClient.Create(context.TODO(), t1) }).Should(Succeed())
EventuallyCreation(func() error { return k8sClient.Create(context.TODO(), t2) }).Should(Succeed())
NamespaceCreation(ns, t1, defaultTimeoutInterval).ShouldNot(Succeed())
NamespaceCreation(ns, t2, defaultTimeoutInterval).ShouldNot(Succeed())
NamespaceCreation(ns, t1.Spec.Owners[0], defaultTimeoutInterval).ShouldNot(Succeed())
NamespaceCreation(ns, t2.Spec.Owners[0], defaultTimeoutInterval).ShouldNot(Succeed())
Expect(k8sClient.Delete(context.TODO(), t1)).Should(Succeed())
Expect(k8sClient.Delete(context.TODO(), t2)).Should(Succeed())
})
By("group owns 2 tenants", func() {
EventuallyCreation(func() error { return k8sClient.Create(context.TODO(), t3) }).Should(Succeed())
EventuallyCreation(func() error { return k8sClient.Create(context.TODO(), t4) }).Should(Succeed())
NamespaceCreation(ns, t3, defaultTimeoutInterval).ShouldNot(Succeed())
NamespaceCreation(ns, t4, defaultTimeoutInterval).ShouldNot(Succeed())
NamespaceCreation(ns, t3.Spec.Owners[0], defaultTimeoutInterval).ShouldNot(Succeed())
NamespaceCreation(ns, t4.Spec.Owners[0], defaultTimeoutInterval).ShouldNot(Succeed())
Expect(k8sClient.Delete(context.TODO(), t3)).Should(Succeed())
Expect(k8sClient.Delete(context.TODO(), t4)).Should(Succeed())
})
@@ -85,10 +93,10 @@ var _ = Describe("creating a Namespace without a Tenant selector when user owns
EventuallyCreation(func() error { return k8sClient.Create(context.TODO(), t2) }).Should(Succeed())
EventuallyCreation(func() error { return k8sClient.Create(context.TODO(), t3) }).Should(Succeed())
EventuallyCreation(func() error { return k8sClient.Create(context.TODO(), t4) }).Should(Succeed())
NamespaceCreation(ns, t1, defaultTimeoutInterval).ShouldNot(Succeed())
NamespaceCreation(ns, t2, defaultTimeoutInterval).ShouldNot(Succeed())
NamespaceCreation(ns, t3, defaultTimeoutInterval).ShouldNot(Succeed())
NamespaceCreation(ns, t4, defaultTimeoutInterval).ShouldNot(Succeed())
NamespaceCreation(ns, t1.Spec.Owners[0], defaultTimeoutInterval).ShouldNot(Succeed())
NamespaceCreation(ns, t2.Spec.Owners[0], defaultTimeoutInterval).ShouldNot(Succeed())
NamespaceCreation(ns, t3.Spec.Owners[0], defaultTimeoutInterval).ShouldNot(Succeed())
NamespaceCreation(ns, t4.Spec.Owners[0], defaultTimeoutInterval).ShouldNot(Succeed())
Expect(k8sClient.Delete(context.TODO(), t1)).Should(Succeed())
Expect(k8sClient.Delete(context.TODO(), t2)).Should(Succeed())
Expect(k8sClient.Delete(context.TODO(), t3)).Should(Succeed())

View File

@@ -21,9 +21,11 @@ var _ = Describe("creating a Namespace with Tenant selector when user owns multi
Name: "tenant-one",
},
Spec: capsulev1beta1.TenantSpec{
Owner: capsulev1beta1.OwnerSpec{
Name: "john",
Kind: "User",
Owners: []capsulev1beta1.OwnerSpec{
{
Name: "john",
Kind: "User",
},
},
},
}
@@ -32,9 +34,11 @@ var _ = Describe("creating a Namespace with Tenant selector when user owns multi
Name: "tenant-two",
},
Spec: capsulev1beta1.TenantSpec{
Owner: capsulev1beta1.OwnerSpec{
Name: "john",
Kind: "User",
Owners: []capsulev1beta1.OwnerSpec{
{
Name: "john",
Kind: "User",
},
},
},
}
@@ -61,7 +65,7 @@ var _ = Describe("creating a Namespace with Tenant selector when user owns multi
l: t2.Name,
}
})
NamespaceCreation(ns, t2, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, t2.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(t2, defaultTimeoutInterval).Should(ContainElement(ns.GetName()))
})
})

View File

@@ -27,9 +27,11 @@ var _ = Describe("adding metadata to Service objects", func() {
Name: "service-metadata",
},
Spec: capsulev1beta1.TenantSpec{
Owner: capsulev1beta1.OwnerSpec{
Name: "gatsby",
Kind: "User",
Owners: []capsulev1beta1.OwnerSpec{
{
Name: "gatsby",
Kind: "User",
},
},
ServicesMetadata: &capsulev1beta1.AdditionalMetadataSpec{
AdditionalLabels: map[string]string{
@@ -67,7 +69,7 @@ var _ = Describe("adding metadata to Service objects", func() {
It("should apply them to Service", func() {
ns := NewNamespace("service-metadata")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, defaultTimeoutInterval).Should(ContainElement(ns.GetName()))
svc := &corev1.Service{
@@ -121,7 +123,7 @@ var _ = Describe("adding metadata to Service objects", func() {
It("should apply them to Endpoints", func() {
ns := NewNamespace("endpoints-metadata")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, defaultTimeoutInterval).Should(ContainElement(ns.GetName()))
ep := &corev1.Endpoints{
@@ -181,7 +183,7 @@ var _ = Describe("adding metadata to Service objects", func() {
}
ns := NewNamespace("endpointslice-metadata")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, defaultTimeoutInterval).Should(ContainElement(ns.GetName()))
eps := &discoveryv1beta1.EndpointSlice{

View File

@@ -24,9 +24,11 @@ var _ = Describe("when Tenant handles Storage classes", func() {
Name: "storage-class",
},
Spec: capsulev1beta1.TenantSpec{
Owner: capsulev1beta1.OwnerSpec{
Name: "storage",
Kind: "User",
Owners: []capsulev1beta1.OwnerSpec{
{
Name: "storage",
Kind: "User",
},
},
StorageClasses: &capsulev1beta1.AllowedListSpec{
Exact: []string{
@@ -50,12 +52,12 @@ var _ = Describe("when Tenant handles Storage classes", func() {
It("should fails", func() {
ns := NewNamespace("storage-class-disallowed")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, defaultTimeoutInterval).Should(ContainElement(ns.GetName()))
By("non-specifying it", func() {
Eventually(func() (err error) {
cs := ownerClient(tnt)
cs := ownerClient(tnt.Spec.Owners[0])
p := &corev1.PersistentVolumeClaim{
ObjectMeta: metav1.ObjectMeta{
Name: "denied-pvc",
@@ -75,7 +77,7 @@ var _ = Describe("when Tenant handles Storage classes", func() {
})
By("specifying a forbidden one", func() {
Eventually(func() (err error) {
cs := ownerClient(tnt)
cs := ownerClient(tnt.Spec.Owners[0])
p := &corev1.PersistentVolumeClaim{
ObjectMeta: metav1.ObjectMeta{
Name: "mighty-storage",
@@ -97,9 +99,9 @@ var _ = Describe("when Tenant handles Storage classes", func() {
It("should allow", func() {
ns := NewNamespace("storage-class-allowed")
cs := ownerClient(tnt)
cs := ownerClient(tnt.Spec.Owners[0])
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, defaultTimeoutInterval).Should(ContainElement(ns.GetName()))
By("using exact matches", func() {
for _, c := range tnt.Spec.StorageClasses.Exact {

View File

@@ -77,11 +77,11 @@ var _ = AfterSuite(func() {
Expect(testEnv.Stop()).ToNot(HaveOccurred())
})
func ownerClient(tenant *capsulev1beta1.Tenant) (cs kubernetes.Interface) {
func ownerClient(owner capsulev1beta1.OwnerSpec) (cs kubernetes.Interface) {
c, err := config.GetConfig()
Expect(err).ToNot(HaveOccurred())
c.Impersonate.Groups = []string{capsulev1beta1.GroupVersion.Group, tenant.Spec.Owner.Name}
c.Impersonate.UserName = tenant.Spec.Owner.Name
c.Impersonate.Groups = []string{capsulev1beta1.GroupVersion.Group, owner.Name}
c.Impersonate.UserName = owner.Name
cs, err = kubernetes.NewForConfig(c)
Expect(err).ToNot(HaveOccurred())
return

View File

@@ -24,9 +24,11 @@ var _ = Describe("cordoning a Tenant", func() {
Name: "tenant-cordoning",
},
Spec: capsulev1beta1.TenantSpec{
Owner: capsulev1beta1.OwnerSpec{
Name: "jim",
Kind: "User",
Owners: []capsulev1beta1.OwnerSpec{
{
Name: "jim",
Kind: "User",
},
},
},
}
@@ -42,7 +44,7 @@ var _ = Describe("cordoning a Tenant", func() {
})
It("should block or allow operations", func() {
cs := ownerClient(tnt)
cs := ownerClient(tnt.Spec.Owners[0])
ns := NewNamespace("cordoned-namespace")
@@ -61,7 +63,7 @@ var _ = Describe("cordoning a Tenant", func() {
}
By("creating a Namespace", func() {
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
EventuallyCreation(func() error {
_, err := cs.CoreV1().Pods(ns.Name).Create(context.Background(), pod, metav1.CreateOptions{})

View File

@@ -23,9 +23,11 @@ var _ = Describe("when a second Tenant contains an already declared allowed Ingr
Name: "allowed-collision-ingress-hostnames",
},
Spec: capsulev1beta1.TenantSpec{
Owner: capsulev1beta1.OwnerSpec{
Name: "first-user",
Kind: "User",
Owners: []capsulev1beta1.OwnerSpec{
{
Name: "first-user",
Kind: "User",
},
},
IngressHostnames: &capsulev1beta1.AllowedListSpec{
Exact: []string{"capsule.clastix.io", "docs.capsule.k8s", "42.clatix.io"},
@@ -57,9 +59,11 @@ var _ = Describe("when a second Tenant contains an already declared allowed Ingr
Name: fmt.Sprintf("%s-%d", tnt.GetName(), i),
},
Spec: capsulev1beta1.TenantSpec{
Owner: capsulev1beta1.OwnerSpec{
Name: "second-user",
Kind: "User",
Owners: []capsulev1beta1.OwnerSpec{
{
Name: "second-user",
Kind: "User",
},
},
IngressHostnames: &capsulev1beta1.AllowedListSpec{
Exact: []string{h},
@@ -96,9 +100,11 @@ var _ = Describe("when a second Tenant contains an already declared allowed Ingr
Name: fmt.Sprintf("%s-%d", tnt.GetName(), i),
},
Spec: capsulev1beta1.TenantSpec{
Owner: capsulev1beta1.OwnerSpec{
Name: "second-user",
Kind: "User",
Owners: []capsulev1beta1.OwnerSpec{
{
Name: "second-user",
Kind: "User",
},
},
IngressHostnames: &capsulev1beta1.AllowedListSpec{
Exact: []string{h},

View File

@@ -22,9 +22,11 @@ var _ = Describe("when a second Tenant contains an already declared allowed Ingr
Name: "no-collision-ingress-hostnames",
},
Spec: capsulev1beta1.TenantSpec{
Owner: capsulev1beta1.OwnerSpec{
Name: "first-user",
Kind: "User",
Owners: []capsulev1beta1.OwnerSpec{
{
Name: "first-user",
Kind: "User",
},
},
IngressHostnames: &capsulev1beta1.AllowedListSpec{
Exact: []string{"capsule.clastix.io", "docs.capsule.k8s", "42.clatix.io"},
@@ -51,9 +53,11 @@ var _ = Describe("when a second Tenant contains an already declared allowed Ingr
Name: fmt.Sprintf("%s-%d", tnt.GetName(), i),
},
Spec: capsulev1beta1.TenantSpec{
Owner: capsulev1beta1.OwnerSpec{
Name: "second-user",
Kind: "User",
Owners: []capsulev1beta1.OwnerSpec{
{
Name: "second-user",
Kind: "User",
},
},
IngressHostnames: &capsulev1beta1.AllowedListSpec{
Exact: []string{h},

View File

@@ -21,9 +21,11 @@ var _ = Describe("creating a Tenant with wrong name", func() {
Name: "non_rfc_dns_1123",
},
Spec: capsulev1beta1.TenantSpec{
Owner: capsulev1beta1.OwnerSpec{
Name: "john",
Kind: "User",
Owners: []capsulev1beta1.OwnerSpec{
{
Name: "john",
Kind: "User",
},
},
},
}

View File

@@ -1,49 +0,0 @@
//+build e2e
// Copyright 2020-2021 Clastix Labs
// SPDX-License-Identifier: Apache-2.0
package e2e
import (
"context"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
capsulev1beta1 "github.com/clastix/capsule/api/v1beta1"
)
var _ = Describe("creating a Namespace with group Tenant owner", func() {
tnt := &capsulev1beta1.Tenant{
ObjectMeta: metav1.ObjectMeta{
Name: "tenant-group-owner",
},
Spec: capsulev1beta1.TenantSpec{
Owner: capsulev1beta1.OwnerSpec{
Name: "alice",
Kind: "Group",
},
},
}
JustBeforeEach(func() {
EventuallyCreation(func() error {
tnt.ResourceVersion = ""
return k8sClient.Create(context.TODO(), tnt)
}).Should(Succeed())
})
JustAfterEach(func() {
Expect(k8sClient.Delete(context.TODO(), tnt)).Should(Succeed())
})
It("should succeed and be available in Tenant namespaces list", func() {
ns := NewNamespace("gto-namespace")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, defaultTimeoutInterval).Should(ContainElement(ns.GetName()))
for _, a := range KindInTenantRoleBindingAssertions(ns, defaultTimeoutInterval) {
a.Should(BeIdenticalTo("Group"))
}
})
})

View File

@@ -27,9 +27,11 @@ var _ = Describe("changing Tenant managed Kubernetes resources", func() {
Name: "tenant-resources-changes",
},
Spec: capsulev1beta1.TenantSpec{
Owner: capsulev1beta1.OwnerSpec{
Name: "laura",
Kind: "User",
Owners: []capsulev1beta1.OwnerSpec{
{
Name: "laura",
Kind: "User",
},
},
LimitRanges: &capsulev1beta1.LimitRangesSpec{Items: []corev1.LimitRangeSpec{
{
@@ -160,7 +162,7 @@ var _ = Describe("changing Tenant managed Kubernetes resources", func() {
By("creating the Namespaces", func() {
for _, i := range nsl {
ns := NewNamespace(i)
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, defaultTimeoutInterval).Should(ContainElement(ns.GetName()))
}
})

View File

@@ -27,9 +27,11 @@ var _ = Describe("creating namespaces within a Tenant with resources", func() {
Name: "tenant-resources",
},
Spec: capsulev1beta1.TenantSpec{
Owner: capsulev1beta1.OwnerSpec{
Name: "john",
Kind: "User",
Owners: []capsulev1beta1.OwnerSpec{
{
Name: "john",
Kind: "User",
},
},
LimitRanges: &capsulev1beta1.LimitRangesSpec{Items: []corev1.LimitRangeSpec{
{
@@ -159,7 +161,7 @@ var _ = Describe("creating namespaces within a Tenant with resources", func() {
By("creating the Namespaces", func() {
for _, i := range nsl {
ns := NewNamespace(i)
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, defaultTimeoutInterval).Should(ContainElement(ns.GetName()))
}
})

View File

@@ -35,8 +35,8 @@ func NewNamespace(name string) *corev1.Namespace {
}
}
func NamespaceCreation(ns *corev1.Namespace, t *capsulev1beta1.Tenant, timeout time.Duration) AsyncAssertion {
cs := ownerClient(t)
func NamespaceCreation(ns *corev1.Namespace, owner capsulev1beta1.OwnerSpec, timeout time.Duration) AsyncAssertion {
cs := ownerClient(owner)
return Eventually(func() (err error) {
_, err = cs.CoreV1().Namespaces().Create(context.TODO(), ns, metav1.CreateOptions{})
return
@@ -68,11 +68,15 @@ func ModifyCapsuleConfigurationOpts(fn func(configuration *capsulev1alpha1.Capsu
func KindInTenantRoleBindingAssertions(ns *corev1.Namespace, timeout time.Duration) (out []AsyncAssertion) {
for _, rbn := range tenantRoleBindingNames {
rb := &rbacv1.RoleBinding{}
out = append(out, Eventually(func() string {
out = append(out, Eventually(func() []string {
if err := k8sClient.Get(context.TODO(), types.NamespacedName{Name: rbn, Namespace: ns.GetName()}, rb); err != nil {
return ""
return nil
}
return rb.Subjects[0].Kind
var subjects []string
for _, subject := range rb.Subjects {
subjects = append(subjects, subject.Kind)
}
return subjects
}, timeout, defaultPollInterval))
}
return