Files
capsule/e2e/owners_test.go
Oliver Bähler 730151cb44 feat: add dynamic capsule user evaluation (#1811)
* chore: improve dev targets

Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>

* feat(controller): implement deterministic rolebinding reflection

Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>

* feat(controller): capsule users are determined from configuration status

Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>

* feat(tenantowners): added agreggate option - tenantowners are always considered capsule users

Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>

* feat(tenantowner): add implicit aggregation for tenants

Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>

* chore: remove helm flags

Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>

* fix(config): remove usergroups default

Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>

---------

Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>
2025-12-31 11:37:30 +01:00

816 lines
21 KiB
Go

// Copyright 2020-2023 Project Capsule Authors.
// SPDX-License-Identifier: Apache-2.0
package e2e
import (
"context"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
capsulev1beta2 "github.com/projectcapsule/capsule/api/v1beta2"
"github.com/projectcapsule/capsule/pkg/api"
"github.com/projectcapsule/capsule/pkg/api/meta"
)
var _ = Describe("Owners", Label("tenant", "permissions", "owners"), func() {
originConfig := &capsulev1beta2.CapsuleConfiguration{}
tnt1 := &capsulev1beta2.Tenant{
ObjectMeta: metav1.ObjectMeta{
Name: "e2e-owners-1",
},
Spec: capsulev1beta2.TenantSpec{
Permissions: capsulev1beta2.Permissions{
MatchOwners: []*metav1.LabelSelector{
{
MatchLabels: map[string]string{
"customer": "x",
},
},
{
MatchLabels: map[string]string{
"team": "devops",
},
},
},
},
Owners: api.OwnerListSpec{
{
CoreOwnerSpec: api.CoreOwnerSpec{
UserSpec: api.UserSpec{
Name: "e2e-owners-1",
Kind: "User",
},
},
},
{
CoreOwnerSpec: api.CoreOwnerSpec{
UserSpec: api.UserSpec{
Name: "e2e-owners-1-group",
Kind: "Group",
},
},
},
{
CoreOwnerSpec: api.CoreOwnerSpec{
UserSpec: api.UserSpec{
Name: "system:serviceaccount:capsule-system:capsule",
Kind: "ServiceAccount",
},
},
},
},
},
}
tnt2 := &capsulev1beta2.Tenant{
ObjectMeta: metav1.ObjectMeta{
Name: "e2e-owners-2",
},
Spec: capsulev1beta2.TenantSpec{
Permissions: capsulev1beta2.Permissions{
MatchOwners: []*metav1.LabelSelector{
{
MatchLabels: map[string]string{
"customer": "x",
},
},
{
MatchLabels: map[string]string{
"team": "infrastructure",
},
},
},
},
Owners: api.OwnerListSpec{
{
CoreOwnerSpec: api.CoreOwnerSpec{
UserSpec: api.UserSpec{
Name: "e2e-owners-2",
Kind: "User",
},
},
},
{
CoreOwnerSpec: api.CoreOwnerSpec{
UserSpec: api.UserSpec{
Name: "e2e-owners-2-group",
Kind: "Group",
},
},
},
{
CoreOwnerSpec: api.CoreOwnerSpec{
UserSpec: api.UserSpec{
Name: "system:serviceaccount:capsule-system:capsule",
Kind: "ServiceAccount",
},
},
},
},
},
}
ownersInfra := &capsulev1beta2.TenantOwner{
ObjectMeta: metav1.ObjectMeta{
Name: "e2e-owners-infra",
Labels: map[string]string{
"team": "infrastructure",
},
},
Spec: capsulev1beta2.TenantOwnerSpec{
Aggregate: true,
CoreOwnerSpec: api.CoreOwnerSpec{
UserSpec: api.UserSpec{
Kind: api.GroupOwner,
Name: "oidc:comp:administrators",
},
ClusterRoles: []string{
"mega-admin",
},
},
},
}
ownersDevops := &capsulev1beta2.TenantOwner{
ObjectMeta: metav1.ObjectMeta{
Name: "e2e-owners-devops",
Labels: map[string]string{
"team": "devops",
},
},
Spec: capsulev1beta2.TenantOwnerSpec{
Aggregate: true,
CoreOwnerSpec: api.CoreOwnerSpec{
UserSpec: api.UserSpec{
Kind: api.GroupOwner,
Name: "oidc:comp:devops",
},
ClusterRoles: []string{
"namespaced-admin",
},
},
},
}
ownersCommon := &capsulev1beta2.TenantOwner{
ObjectMeta: metav1.ObjectMeta{
Name: "e2e-owners-common",
Labels: map[string]string{
"team": "infrastructure",
"customer": "x",
},
},
Spec: capsulev1beta2.TenantOwnerSpec{
Aggregate: true,
CoreOwnerSpec: api.CoreOwnerSpec{
UserSpec: api.UserSpec{
Kind: api.ServiceAccountOwner,
Name: "system:serviceaccount:capsule-system:capsule",
},
ClusterRoles: []string{
"service-admin",
},
},
},
}
tnt1Owner := &capsulev1beta2.TenantOwner{
ObjectMeta: metav1.ObjectMeta{
Name: "e2e-owners-tnt",
Labels: map[string]string{
meta.NewTenantLabel: tnt1.GetName(),
},
},
Spec: capsulev1beta2.TenantOwnerSpec{
Aggregate: true,
CoreOwnerSpec: api.CoreOwnerSpec{
UserSpec: api.UserSpec{
Kind: api.UserOwner,
Name: "tnt-1-user",
},
ClusterRoles: []string{
"service-admin",
},
},
},
}
userOwnersCommon := &capsulev1beta2.TenantOwner{
ObjectMeta: metav1.ObjectMeta{
Name: "e2e-owners-common-user",
Labels: map[string]string{
"team": "infrastructure",
"customer": "x",
},
},
Spec: capsulev1beta2.TenantOwnerSpec{
Aggregate: false,
CoreOwnerSpec: api.CoreOwnerSpec{
UserSpec: api.UserSpec{
Kind: api.UserOwner,
Name: "some-user",
},
ClusterRoles: []string{
"service-admin",
},
},
},
}
JustBeforeEach(func() {
Expect(k8sClient.Get(context.Background(), client.ObjectKey{Name: defaultConfigurationName}, originConfig)).To(Succeed())
for _, tnt := range []*capsulev1beta2.Tenant{tnt1, tnt2} {
EventuallyCreation(func() error {
tnt.ResourceVersion = ""
return k8sClient.Create(context.TODO(), tnt)
}).Should(Succeed())
}
for _, tnt := range []*capsulev1beta2.TenantOwner{ownersInfra, ownersDevops, ownersCommon, userOwnersCommon, tnt1Owner} {
EventuallyCreation(func() error {
tnt.ResourceVersion = ""
return k8sClient.Create(context.TODO(), tnt)
}).Should(Succeed())
}
})
JustAfterEach(func() {
for _, tnt := range []*capsulev1beta2.Tenant{tnt1, tnt2} {
err := k8sClient.Delete(context.TODO(), tnt)
Expect(client.IgnoreNotFound(err)).To(Succeed())
}
for _, owners := range []*capsulev1beta2.TenantOwner{ownersInfra, ownersDevops, ownersCommon, userOwnersCommon, tnt1Owner} {
err := k8sClient.Delete(context.TODO(), owners)
Expect(client.IgnoreNotFound(err)).To(Succeed())
}
})
It("Verify owners for", func() {
By("checking configuration", func() {
Eventually(func(g Gomega) {
cfg := &capsulev1beta2.CapsuleConfiguration{}
err := k8sClient.Get(
context.Background(),
client.ObjectKey{Name: defaultConfigurationName},
cfg,
)
g.Expect(err).ToNot(HaveOccurred())
expected := api.UserListSpec{
{Kind: ownersInfra.Spec.Kind, Name: ownersInfra.Spec.Name},
{Kind: ownersDevops.Spec.Kind, Name: ownersDevops.Spec.Name},
{Kind: ownersCommon.Spec.Kind, Name: ownersCommon.Spec.Name},
{Kind: tnt1Owner.Spec.Kind, Name: tnt1Owner.Spec.Name},
{Kind: api.GroupOwner, Name: "projectcapsule.dev"},
}
g.Expect(cfg.Status.Users).To(ConsistOf(expected))
g.Expect(cfg.Status.Users).NotTo(ContainElement(
api.UserSpec{Kind: userOwnersCommon.Spec.Kind, Name: userOwnersCommon.Spec.Name},
))
}, defaultTimeoutInterval, defaultPollInterval).Should(Succeed())
})
By("checking owners (e2e-owners-1)", func() {
t := &capsulev1beta2.Tenant{}
Expect(k8sClient.Get(context.TODO(), types.NamespacedName{Name: tnt1.GetName()}, t)).Should(Succeed())
expectedOwners := api.OwnerStatusListSpec{
{
UserSpec: api.UserSpec{
Kind: api.GroupOwner,
Name: "e2e-owners-1-group",
},
ClusterRoles: []string{"admin", "capsule-namespace-deleter"},
},
{
UserSpec: api.UserSpec{
Kind: api.GroupOwner,
Name: "oidc:comp:devops",
},
ClusterRoles: []string{"namespaced-admin"},
},
{
UserSpec: api.UserSpec{
Kind: api.ServiceAccountOwner,
Name: "system:serviceaccount:capsule-system:capsule",
},
ClusterRoles: []string{"admin", "capsule-namespace-deleter", "service-admin"},
},
{
UserSpec: api.UserSpec{
Kind: api.UserOwner,
Name: "e2e-owners-1",
},
ClusterRoles: []string{"admin", "capsule-namespace-deleter"},
},
{
UserSpec: api.UserSpec{
Kind: userOwnersCommon.Spec.Kind,
Name: userOwnersCommon.Spec.Name,
},
ClusterRoles: []string{"service-admin"},
},
{
UserSpec: api.UserSpec{
Kind: tnt1Owner.Spec.Kind,
Name: tnt1Owner.Spec.Name,
},
ClusterRoles: []string{"service-admin"},
},
}
Expect(normalizeOwners(t.Status.Owners)).
To(Equal(normalizeOwners(expectedOwners)))
VerifyTenantRoleBindings(t)
})
By("creating namespaces (e2e-owners-1)", func() {
for _, u := range []api.UserSpec{
api.UserSpec{
Kind: api.GroupOwner,
Name: "e2e-owners-1-group",
},
api.UserSpec{
Kind: api.GroupOwner,
Name: "oidc:comp:devops",
},
api.UserSpec{
Kind: api.ServiceAccountOwner,
Name: "system:serviceaccount:capsule-system:capsule",
},
api.UserSpec{
Kind: api.UserOwner,
Name: "e2e-owners-1",
},
api.UserSpec{
Kind: userOwnersCommon.Spec.Kind,
Name: userOwnersCommon.Spec.Name,
},
api.UserSpec{
Kind: tnt1Owner.Spec.Kind,
Name: tnt1Owner.Spec.Name,
},
} {
ns := NewNamespace("", map[string]string{
meta.TenantLabel: tnt1.GetName(),
})
NamespaceCreation(ns, u, defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt1, defaultTimeoutInterval).Should(ContainElements(ns.GetName()))
}
})
By("checking owners (e2e-owners-2)", func() {
t := &capsulev1beta2.Tenant{}
Expect(k8sClient.Get(context.TODO(), types.NamespacedName{Name: tnt2.GetName()}, t)).Should(Succeed())
expectedOwners := api.OwnerStatusListSpec{
{
UserSpec: api.UserSpec{
Kind: api.GroupOwner,
Name: "e2e-owners-2-group",
},
ClusterRoles: []string{"admin", "capsule-namespace-deleter"},
},
{
UserSpec: api.UserSpec{
Kind: api.GroupOwner,
Name: "oidc:comp:administrators",
},
ClusterRoles: []string{"mega-admin"},
},
{
UserSpec: api.UserSpec{
Kind: api.ServiceAccountOwner,
Name: "system:serviceaccount:capsule-system:capsule",
},
ClusterRoles: []string{"admin", "capsule-namespace-deleter", "service-admin"},
},
{
UserSpec: api.UserSpec{
Kind: api.UserOwner,
Name: "e2e-owners-2",
},
ClusterRoles: []string{"admin", "capsule-namespace-deleter"},
},
{
UserSpec: api.UserSpec{
Kind: userOwnersCommon.Spec.Kind,
Name: userOwnersCommon.Spec.Name,
},
ClusterRoles: []string{"service-admin"},
},
}
Expect(normalizeOwners(t.Status.Owners)).
To(Equal(normalizeOwners(expectedOwners)))
VerifyTenantRoleBindings(t)
})
By("creating namespaces (e2e-owners-2)", func() {
for _, u := range []api.UserSpec{
api.UserSpec{
Kind: api.GroupOwner,
Name: "e2e-owners-2-group",
},
api.UserSpec{
Kind: api.GroupOwner,
Name: "oidc:comp:administrators",
},
api.UserSpec{
Kind: api.ServiceAccountOwner,
Name: "system:serviceaccount:capsule-system:capsule",
},
api.UserSpec{
Kind: api.UserOwner,
Name: "e2e-owners-2",
},
api.UserSpec{
Kind: userOwnersCommon.Spec.Kind,
Name: userOwnersCommon.Spec.Name,
},
} {
ns := NewNamespace("", map[string]string{
meta.TenantLabel: tnt2.GetName(),
})
NamespaceCreation(ns, u, defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt2, defaultTimeoutInterval).Should(ContainElements(ns.GetName()))
}
})
By("remove common tenant-owners", func() {
Expect(k8sClient.Delete(context.TODO(), ownersCommon)).Should(Succeed())
})
By("checking configuration", func() {
Eventually(func(g Gomega) {
cfg := &capsulev1beta2.CapsuleConfiguration{}
err := k8sClient.Get(
context.Background(),
client.ObjectKey{Name: defaultConfigurationName},
cfg,
)
g.Expect(err).ToNot(HaveOccurred())
expected := api.UserListSpec{
{Kind: ownersInfra.Spec.Kind, Name: ownersInfra.Spec.Name},
{Kind: ownersDevops.Spec.Kind, Name: ownersDevops.Spec.Name},
{Kind: tnt1Owner.Spec.Kind, Name: tnt1Owner.Spec.Name},
{Kind: api.GroupOwner, Name: "projectcapsule.dev"},
}
g.Expect(cfg.Status.Users).To(ConsistOf(expected))
}, defaultTimeoutInterval, defaultPollInterval).Should(Succeed())
})
By("checking owners (e2e-owners-1)", func() {
t := &capsulev1beta2.Tenant{}
Expect(k8sClient.Get(context.TODO(), types.NamespacedName{Name: tnt1.GetName()}, t)).Should(Succeed())
expectedOwners := api.OwnerStatusListSpec{
{
UserSpec: api.UserSpec{
Kind: api.GroupOwner,
Name: "e2e-owners-1-group",
},
ClusterRoles: []string{"admin", "capsule-namespace-deleter"},
},
{
UserSpec: api.UserSpec{
Kind: api.GroupOwner,
Name: "oidc:comp:devops",
},
ClusterRoles: []string{"namespaced-admin"},
},
{
UserSpec: api.UserSpec{
Kind: api.ServiceAccountOwner,
Name: "system:serviceaccount:capsule-system:capsule",
},
ClusterRoles: []string{"admin", "capsule-namespace-deleter"},
},
{
UserSpec: api.UserSpec{
Kind: api.UserOwner,
Name: "e2e-owners-1",
},
ClusterRoles: []string{"admin", "capsule-namespace-deleter"},
},
{
UserSpec: api.UserSpec{
Kind: userOwnersCommon.Spec.Kind,
Name: userOwnersCommon.Spec.Name,
},
ClusterRoles: []string{"service-admin"},
},
{
UserSpec: api.UserSpec{
Kind: tnt1Owner.Spec.Kind,
Name: tnt1Owner.Spec.Name,
},
ClusterRoles: []string{"service-admin"},
},
}
Expect(normalizeOwners(t.Status.Owners)).
To(Equal(normalizeOwners(expectedOwners)))
VerifyTenantRoleBindings(t)
})
By("checking owners (e2e-owners-2)", func() {
t := &capsulev1beta2.Tenant{}
Expect(k8sClient.Get(context.TODO(), types.NamespacedName{Name: tnt2.GetName()}, t)).Should(Succeed())
expectedOwners := api.OwnerStatusListSpec{
{
UserSpec: api.UserSpec{
Kind: api.GroupOwner,
Name: "e2e-owners-2-group",
},
ClusterRoles: []string{"admin", "capsule-namespace-deleter"},
},
{
UserSpec: api.UserSpec{
Kind: api.GroupOwner,
Name: "oidc:comp:administrators",
},
ClusterRoles: []string{"mega-admin"},
},
{
UserSpec: api.UserSpec{
Kind: api.ServiceAccountOwner,
Name: "system:serviceaccount:capsule-system:capsule",
},
ClusterRoles: []string{"admin", "capsule-namespace-deleter"},
},
{
UserSpec: api.UserSpec{
Kind: api.UserOwner,
Name: "e2e-owners-2",
},
ClusterRoles: []string{"admin", "capsule-namespace-deleter"},
},
{
UserSpec: api.UserSpec{
Kind: userOwnersCommon.Spec.Kind,
Name: userOwnersCommon.Spec.Name,
},
ClusterRoles: []string{"service-admin"},
},
}
Expect(normalizeOwners(t.Status.Owners)).
To(Equal(normalizeOwners(expectedOwners)))
VerifyTenantRoleBindings(t)
})
By("remove admin tenant-owners", func() {
Expect(k8sClient.Delete(context.TODO(), ownersInfra)).Should(Succeed())
})
By("checking configuration", func() {
Eventually(func(g Gomega) {
cfg := &capsulev1beta2.CapsuleConfiguration{}
err := k8sClient.Get(
context.Background(),
client.ObjectKey{Name: defaultConfigurationName},
cfg,
)
g.Expect(err).ToNot(HaveOccurred())
expected := api.UserListSpec{
{Kind: ownersDevops.Spec.Kind, Name: ownersDevops.Spec.Name},
{Kind: tnt1Owner.Spec.Kind, Name: tnt1Owner.Spec.Name},
{Kind: api.GroupOwner, Name: "projectcapsule.dev"},
}
g.Expect(cfg.Status.Users).To(ConsistOf(expected))
}, defaultTimeoutInterval, defaultPollInterval).Should(Succeed())
})
By("checking owners (e2e-owners-1)", func() {
t := &capsulev1beta2.Tenant{}
Expect(k8sClient.Get(context.TODO(), types.NamespacedName{Name: tnt1.GetName()}, t)).Should(Succeed())
expectedOwners := api.OwnerStatusListSpec{
{
UserSpec: api.UserSpec{
Kind: api.GroupOwner,
Name: "e2e-owners-1-group",
},
ClusterRoles: []string{"admin", "capsule-namespace-deleter"},
},
{
UserSpec: api.UserSpec{
Kind: api.GroupOwner,
Name: "oidc:comp:devops",
},
ClusterRoles: []string{"namespaced-admin"},
},
{
UserSpec: api.UserSpec{
Kind: api.ServiceAccountOwner,
Name: "system:serviceaccount:capsule-system:capsule",
},
ClusterRoles: []string{"admin", "capsule-namespace-deleter"},
},
{
UserSpec: api.UserSpec{
Kind: api.UserOwner,
Name: "e2e-owners-1",
},
ClusterRoles: []string{"admin", "capsule-namespace-deleter"},
},
{
UserSpec: api.UserSpec{
Kind: userOwnersCommon.Spec.Kind,
Name: userOwnersCommon.Spec.Name,
},
ClusterRoles: []string{"service-admin"},
},
{
UserSpec: api.UserSpec{
Kind: tnt1Owner.Spec.Kind,
Name: tnt1Owner.Spec.Name,
},
ClusterRoles: []string{"service-admin"},
},
}
Expect(normalizeOwners(t.Status.Owners)).
To(Equal(normalizeOwners(expectedOwners)))
VerifyTenantRoleBindings(t)
})
By("checking owners (e2e-owners-2)", func() {
t := &capsulev1beta2.Tenant{}
Expect(k8sClient.Get(context.TODO(), types.NamespacedName{Name: tnt2.GetName()}, t)).Should(Succeed())
expectedOwners := api.OwnerStatusListSpec{
{
UserSpec: api.UserSpec{
Kind: api.GroupOwner,
Name: "e2e-owners-2-group",
},
ClusterRoles: []string{"admin", "capsule-namespace-deleter"},
},
{
UserSpec: api.UserSpec{
Kind: api.ServiceAccountOwner,
Name: "system:serviceaccount:capsule-system:capsule",
},
ClusterRoles: []string{"admin", "capsule-namespace-deleter"},
},
{
UserSpec: api.UserSpec{
Kind: api.UserOwner,
Name: "e2e-owners-2",
},
ClusterRoles: []string{"admin", "capsule-namespace-deleter"},
},
{
UserSpec: api.UserSpec{
Kind: userOwnersCommon.Spec.Kind,
Name: userOwnersCommon.Spec.Name,
},
ClusterRoles: []string{"service-admin"},
},
}
Expect(normalizeOwners(t.Status.Owners)).
To(Equal(normalizeOwners(expectedOwners)))
VerifyTenantRoleBindings(t)
})
By("remove admin tenant-owners", func() {
Expect(k8sClient.Delete(context.TODO(), ownersDevops)).Should(Succeed())
})
By("checking configuration", func() {
Eventually(func(g Gomega) {
cfg := &capsulev1beta2.CapsuleConfiguration{}
err := k8sClient.Get(
context.Background(),
client.ObjectKey{Name: defaultConfigurationName},
cfg,
)
g.Expect(err).ToNot(HaveOccurred())
expected := api.UserListSpec{
{Kind: tnt1Owner.Spec.Kind, Name: tnt1Owner.Spec.Name},
{Kind: api.GroupOwner, Name: "projectcapsule.dev"},
}
g.Expect(cfg.Status.Users).To(ConsistOf(expected))
}, defaultTimeoutInterval, defaultPollInterval).Should(Succeed())
})
By("checking owners (e2e-owners-1)", func() {
t := &capsulev1beta2.Tenant{}
Expect(k8sClient.Get(context.TODO(), types.NamespacedName{Name: tnt1.GetName()}, t)).Should(Succeed())
expectedOwners := api.OwnerStatusListSpec{
{
UserSpec: api.UserSpec{
Kind: api.GroupOwner,
Name: "e2e-owners-1-group",
},
ClusterRoles: []string{"admin", "capsule-namespace-deleter"},
},
{
UserSpec: api.UserSpec{
Kind: api.ServiceAccountOwner,
Name: "system:serviceaccount:capsule-system:capsule",
},
ClusterRoles: []string{"admin", "capsule-namespace-deleter"},
},
{
UserSpec: api.UserSpec{
Kind: api.UserOwner,
Name: "e2e-owners-1",
},
ClusterRoles: []string{"admin", "capsule-namespace-deleter"},
},
{
UserSpec: api.UserSpec{
Kind: userOwnersCommon.Spec.Kind,
Name: userOwnersCommon.Spec.Name,
},
ClusterRoles: []string{"service-admin"},
},
{
UserSpec: api.UserSpec{
Kind: tnt1Owner.Spec.Kind,
Name: tnt1Owner.Spec.Name,
},
ClusterRoles: []string{"service-admin"},
},
}
Expect(normalizeOwners(t.Status.Owners)).
To(Equal(normalizeOwners(expectedOwners)))
VerifyTenantRoleBindings(t)
})
By("checking owners (e2e-owners-2)", func() {
t := &capsulev1beta2.Tenant{}
Expect(k8sClient.Get(context.TODO(), types.NamespacedName{Name: tnt2.GetName()}, t)).Should(Succeed())
expectedOwners := api.OwnerStatusListSpec{
{
UserSpec: api.UserSpec{
Kind: api.GroupOwner,
Name: "e2e-owners-2-group",
},
ClusterRoles: []string{"admin", "capsule-namespace-deleter"},
},
{
UserSpec: api.UserSpec{
Kind: api.ServiceAccountOwner,
Name: "system:serviceaccount:capsule-system:capsule",
},
ClusterRoles: []string{"admin", "capsule-namespace-deleter"},
},
{
UserSpec: api.UserSpec{
Kind: api.UserOwner,
Name: "e2e-owners-2",
},
ClusterRoles: []string{"admin", "capsule-namespace-deleter"},
},
{
UserSpec: api.UserSpec{
Kind: userOwnersCommon.Spec.Kind,
Name: userOwnersCommon.Spec.Name,
},
ClusterRoles: []string{"service-admin"},
},
}
Expect(normalizeOwners(t.Status.Owners)).
To(Equal(normalizeOwners(expectedOwners)))
VerifyTenantRoleBindings(t)
})
})
})