mirror of
https://github.com/projectcapsule/capsule.git
synced 2026-08-19 12:36:39 +00:00
* feat: add rolebindings to rules api Signed-off-by: Oliver Baehler <oliver@sudo-i.net> * feat: add rolebindings to rules api Signed-off-by: Oliver Baehler <oliver@sudo-i.net> * feat: add rolebindings to rules api Signed-off-by: Oliver Baehler <oliver@sudo-i.net> * feat: add rolebindings to rules api Signed-off-by: Oliver Baehler <oliver@sudo-i.net> * feat: add rolebindings to rules api Signed-off-by: Oliver Baehler <oliver@sudo-i.net> * feat: implement review Signed-off-by: Oliver Baehler <oliver@sudo-i.net> --------- Signed-off-by: Oliver Baehler <oliver@sudo-i.net>
194 lines
4.9 KiB
Go
194 lines
4.9 KiB
Go
// Copyright 2020-2026 Project Capsule Authors
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package utils_test
|
|
|
|
import (
|
|
"testing"
|
|
|
|
rbacv1 "k8s.io/api/rbac/v1"
|
|
|
|
"github.com/projectcapsule/capsule/pkg/api/rbac"
|
|
"github.com/projectcapsule/capsule/pkg/utils"
|
|
)
|
|
|
|
func TestRoleBindingHashFunc_Deterministic(t *testing.T) {
|
|
b := rbac.AdditionalRoleBindingsSpec{
|
|
ClusterRoleName: "admin",
|
|
Subjects: []rbacv1.Subject{
|
|
{Kind: "User", Name: "alice"},
|
|
{Kind: "Group", Name: "devops"},
|
|
},
|
|
}
|
|
|
|
h1 := utils.RoleBindingHashFunc(b)
|
|
h2 := utils.RoleBindingHashFunc(b)
|
|
|
|
if h1 != h2 {
|
|
t.Fatalf("expected deterministic hash, got %q and %q", h1, h2)
|
|
}
|
|
if h1 == "" {
|
|
t.Fatalf("expected non-empty hash")
|
|
}
|
|
}
|
|
|
|
func TestRoleBindingHashFunc_ChangesWhenClusterRoleChanges(t *testing.T) {
|
|
b1 := rbac.AdditionalRoleBindingsSpec{
|
|
ClusterRoleName: "admin",
|
|
Subjects: []rbacv1.Subject{{Kind: "User", Name: "alice"}},
|
|
}
|
|
b2 := rbac.AdditionalRoleBindingsSpec{
|
|
ClusterRoleName: "view",
|
|
Subjects: []rbacv1.Subject{{Kind: "User", Name: "alice"}},
|
|
}
|
|
|
|
h1 := utils.RoleBindingHashFunc(b1)
|
|
h2 := utils.RoleBindingHashFunc(b2)
|
|
|
|
if h1 == h2 {
|
|
t.Fatalf("expected different hashes when ClusterRoleName changes, got %q", h1)
|
|
}
|
|
}
|
|
|
|
func TestRoleBindingHashFunc_ChangesWhenSubjectKindChanges(t *testing.T) {
|
|
b1 := rbac.AdditionalRoleBindingsSpec{
|
|
ClusterRoleName: "admin",
|
|
Subjects: []rbacv1.Subject{{Kind: "User", Name: "alice"}},
|
|
}
|
|
b2 := rbac.AdditionalRoleBindingsSpec{
|
|
ClusterRoleName: "admin",
|
|
Subjects: []rbacv1.Subject{{Kind: "Group", Name: "alice"}},
|
|
}
|
|
|
|
h1 := utils.RoleBindingHashFunc(b1)
|
|
h2 := utils.RoleBindingHashFunc(b2)
|
|
|
|
if h1 == h2 {
|
|
t.Fatalf("expected different hashes when subject Kind changes, got %q", h1)
|
|
}
|
|
}
|
|
|
|
func TestRoleBindingHashFunc_ChangesWhenSubjectNameChanges(t *testing.T) {
|
|
b1 := rbac.AdditionalRoleBindingsSpec{
|
|
ClusterRoleName: "admin",
|
|
Subjects: []rbacv1.Subject{{Kind: "User", Name: "alice"}},
|
|
}
|
|
b2 := rbac.AdditionalRoleBindingsSpec{
|
|
ClusterRoleName: "admin",
|
|
Subjects: []rbacv1.Subject{{Kind: "User", Name: "bob"}},
|
|
}
|
|
|
|
h1 := utils.RoleBindingHashFunc(b1)
|
|
h2 := utils.RoleBindingHashFunc(b2)
|
|
|
|
if h1 == h2 {
|
|
t.Fatalf("expected different hashes when subject Name changes, got %q", h1)
|
|
}
|
|
}
|
|
|
|
func TestRoleBindingHashFunc_ChangesWhenSubjectNamespaceChanges(t *testing.T) {
|
|
b1 := rbac.AdditionalRoleBindingsSpec{
|
|
ClusterRoleName: "admin",
|
|
Subjects: []rbacv1.Subject{{
|
|
Kind: rbacv1.ServiceAccountKind,
|
|
Namespace: "team-a",
|
|
Name: "deployer",
|
|
}},
|
|
}
|
|
b2 := rbac.AdditionalRoleBindingsSpec{
|
|
ClusterRoleName: "admin",
|
|
Subjects: []rbacv1.Subject{{
|
|
Kind: rbacv1.ServiceAccountKind,
|
|
Namespace: "team-b",
|
|
Name: "deployer",
|
|
}},
|
|
}
|
|
|
|
h1 := utils.RoleBindingHashFunc(b1)
|
|
h2 := utils.RoleBindingHashFunc(b2)
|
|
|
|
if h1 == h2 {
|
|
t.Fatalf("expected different hashes when subject Namespace changes, got %q", h1)
|
|
}
|
|
}
|
|
|
|
func TestRoleBindingHashFunc_ChangesWhenSubjectAPIGroupChanges(t *testing.T) {
|
|
b1 := rbac.AdditionalRoleBindingsSpec{
|
|
ClusterRoleName: "admin",
|
|
Subjects: []rbacv1.Subject{{
|
|
APIGroup: rbacv1.GroupName,
|
|
Kind: rbacv1.UserKind,
|
|
Name: "alice",
|
|
}},
|
|
}
|
|
b2 := rbac.AdditionalRoleBindingsSpec{
|
|
ClusterRoleName: "admin",
|
|
Subjects: []rbacv1.Subject{{
|
|
APIGroup: "example.com",
|
|
Kind: rbacv1.UserKind,
|
|
Name: "alice",
|
|
}},
|
|
}
|
|
|
|
h1 := utils.RoleBindingHashFunc(b1)
|
|
h2 := utils.RoleBindingHashFunc(b2)
|
|
|
|
if h1 == h2 {
|
|
t.Fatalf("expected different hashes when subject APIGroup changes, got %q", h1)
|
|
}
|
|
}
|
|
|
|
func TestRoleBindingHashFunc_UsesUnambiguousFieldBoundaries(t *testing.T) {
|
|
b1 := rbac.AdditionalRoleBindingsSpec{
|
|
ClusterRoleName: "ab",
|
|
Subjects: []rbacv1.Subject{{Kind: "c", Name: "d"}},
|
|
}
|
|
b2 := rbac.AdditionalRoleBindingsSpec{
|
|
ClusterRoleName: "a",
|
|
Subjects: []rbacv1.Subject{{Kind: "bc", Name: "d"}},
|
|
}
|
|
|
|
h1 := utils.RoleBindingHashFunc(b1)
|
|
h2 := utils.RoleBindingHashFunc(b2)
|
|
|
|
if h1 == h2 {
|
|
t.Fatalf("expected different hashes for differently bounded fields, got %q", h1)
|
|
}
|
|
}
|
|
|
|
func TestRoleBindingHashFunc_EmptyInputsStillProduceHash(t *testing.T) {
|
|
b := rbac.AdditionalRoleBindingsSpec{
|
|
ClusterRoleName: "",
|
|
Subjects: nil,
|
|
}
|
|
|
|
h := utils.RoleBindingHashFunc(b)
|
|
if h == "" {
|
|
t.Fatalf("expected non-empty hash even for empty input")
|
|
}
|
|
}
|
|
|
|
func TestRoleBindingHashFunc_SubjectOrderMatters(t *testing.T) {
|
|
b1 := rbac.AdditionalRoleBindingsSpec{
|
|
ClusterRoleName: "admin",
|
|
Subjects: []rbacv1.Subject{
|
|
{Kind: "User", Name: "alice"},
|
|
{Kind: "Group", Name: "devops"},
|
|
},
|
|
}
|
|
b2 := rbac.AdditionalRoleBindingsSpec{
|
|
ClusterRoleName: "admin",
|
|
Subjects: []rbacv1.Subject{
|
|
{Kind: "Group", Name: "devops"},
|
|
{Kind: "User", Name: "alice"},
|
|
},
|
|
}
|
|
|
|
h1 := utils.RoleBindingHashFunc(b1)
|
|
h2 := utils.RoleBindingHashFunc(b2)
|
|
|
|
if h1 == h2 {
|
|
t.Fatalf("expected different hashes when subject order changes, got %q", h1)
|
|
}
|
|
}
|