Files
capsule/pkg/api/meta/metadata_test.go
T
77d1810bb9 feat: add metadata enforcement (#1990)
* fix(controller): decode old object for delete requests

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

* chore: modernize golang

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

* chore: modernize golang

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

* chore: modernize golang

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

* fix: preserve ca-bundles injected from external providers

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

* feat: add metadata enforcement

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

* feat: add metadata enforcement

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

* fix: add resourcepoolclaim validation

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

* fix: add resourcepoolclaim validation

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

* fix: add resourcepoolclaim validation

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* fix: add resourcepoolclaim validation

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

---------

Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>
Signed-off-by: Oliver Baehler <oliver@sudo-i.net>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-07-02 13:42:08 +02:00

851 lines
16 KiB
Go

// Copyright 2020-2026 Project Capsule Authors
// SPDX-License-Identifier: Apache-2.0
package meta
import (
"reflect"
"testing"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func TestNewManagedMetadata(t *testing.T) {
t.Parallel()
t.Run("contains default managed labels", func(t *testing.T) {
t.Parallel()
m := NewManagedMetadata(nil, nil)
for _, key := range []string{
ResourcesLabel,
TenantNameLabel,
TenantLabel,
NewTenantLabel,
ResourcePoolLabel,
FreezeLabel,
OwnerPromotionLabel,
ServiceAccountPromotionLabel,
CordonedLabel,
CapsuleNameLabel,
CreatedByCapsuleLabel,
CustomResourcesLabel,
NewManagedByCapsuleLabel,
ManagedByCapsuleLabel,
LimitRangeLabel,
NetworkPolicyLabel,
ResourceQuotaLabel,
RolebindingLabel,
} {
if !m.HasLabel(key) {
t.Fatalf("expected managed label %q", key)
}
}
})
t.Run("contains default managed annotations", func(t *testing.T) {
t.Parallel()
m := NewManagedMetadata(nil, nil)
for _, key := range []string{
ReleaseAnnotation,
ReconcileAnnotation,
AvailableIngressClassesAnnotation,
AvailableIngressClassesRegexpAnnotation,
AvailableStorageClassesAnnotation,
AvailableStorageClassesRegexpAnnotation,
AllowedRegistriesAnnotation,
AllowedRegistriesRegexpAnnotation,
ForbiddenNamespaceLabelsAnnotation,
ForbiddenNamespaceLabelsRegexpAnnotation,
ForbiddenNamespaceAnnotationsAnnotation,
ForbiddenNamespaceAnnotationsRegexpAnnotation,
ProtectedTenantAnnotation,
} {
if !m.HasAnnotation(key) {
t.Fatalf("expected managed annotation %q", key)
}
}
})
t.Run("contains default managed annotation prefixes", func(t *testing.T) {
t.Parallel()
m := NewManagedMetadata(nil, nil)
for _, key := range []string{
ResourceQuotaAnnotationPrefix + "cpu",
ResourceQuotaAnnotationPrefix + "memory",
ResourceUsedAnnotationPrefix + "cpu",
ResourceUsedAnnotationPrefix + "memory",
} {
if !m.HasAnnotation(key) {
t.Fatalf("expected managed annotation prefix match for %q", key)
}
}
})
t.Run("adds custom managed labels and annotations", func(t *testing.T) {
t.Parallel()
m := NewManagedMetadata(
[]string{
"example.corp/label",
" example.corp/trimmed-label ",
"",
" ",
},
[]string{
"example.corp/annotation",
" example.corp/trimmed-annotation ",
"",
" ",
},
)
for _, key := range []string{
"example.corp/label",
"example.corp/trimmed-label",
} {
if !m.HasLabel(key) {
t.Fatalf("expected custom managed label %q", key)
}
}
for _, key := range []string{
"example.corp/annotation",
"example.corp/trimmed-annotation",
} {
if !m.HasAnnotation(key) {
t.Fatalf("expected custom managed annotation %q", key)
}
}
if m.HasLabel("") {
t.Fatalf("empty label must not be managed")
}
if m.HasAnnotation("") {
t.Fatalf("empty annotation must not be managed")
}
})
t.Run("matching is exact and case-sensitive", func(t *testing.T) {
t.Parallel()
m := NewManagedMetadata(
[]string{
"example.corp/managed",
},
[]string{
"example.corp/managed",
},
)
if !m.HasLabel("example.corp/managed") {
t.Fatalf("expected exact label match")
}
if m.HasLabel("Example.Corp/managed") {
t.Fatalf("expected label lookup to be case-sensitive")
}
if m.HasLabel(" example.corp/managed ") {
t.Fatalf("expected label lookup not to trim lookup key")
}
if !m.HasAnnotation("example.corp/managed") {
t.Fatalf("expected exact annotation match")
}
if m.HasAnnotation("Example.Corp/managed") {
t.Fatalf("expected annotation lookup to be case-sensitive")
}
if m.HasAnnotation(" example.corp/managed ") {
t.Fatalf("expected annotation lookup not to trim lookup key")
}
})
t.Run("unknown metadata is not managed", func(t *testing.T) {
t.Parallel()
m := NewManagedMetadata(nil, nil)
if m.HasLabel("example.corp/not-managed") {
t.Fatalf("unexpected managed label")
}
if m.HasAnnotation("example.corp/not-managed") {
t.Fatalf("unexpected managed annotation")
}
})
}
func TestStringSet(t *testing.T) {
t.Parallel()
tests := []struct {
name string
in []string
want map[string]struct{}
}{
{
name: "empty input returns nil",
in: nil,
want: nil,
},
{
name: "trims values skips blanks and deduplicates",
in: []string{
"alpha",
" alpha ",
"",
" ",
"beta",
},
want: map[string]struct{}{
"alpha": {},
"beta": {},
},
},
{
name: "case sensitive",
in: []string{
"alpha",
"Alpha",
},
want: map[string]struct{}{
"alpha": {},
"Alpha": {},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
got := stringSet(tt.in...)
if !reflect.DeepEqual(got, tt.want) {
t.Fatalf("expected %#v, got %#v", tt.want, got)
}
})
}
}
func TestCompactStrings(t *testing.T) {
t.Parallel()
tests := []struct {
name string
in []string
want []string
}{
{
name: "empty input returns nil",
in: nil,
want: nil,
},
{
name: "trims values and skips blanks",
in: []string{
"alpha",
" alpha ",
"",
" ",
"beta",
},
want: []string{
"alpha",
"alpha",
"beta",
},
},
{
name: "does not deduplicate prefixes",
in: []string{
"alpha/",
"alpha/",
},
want: []string{
"alpha/",
"alpha/",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
got := compactStrings(tt.in...)
if !reflect.DeepEqual(got, tt.want) {
t.Fatalf("expected %#v, got %#v", tt.want, got)
}
})
}
}
func TestAddStrings(t *testing.T) {
t.Parallel()
set := map[string]struct{}{
"existing": {},
}
addStrings(
set,
"alpha",
" alpha ",
"",
" ",
"beta",
)
want := map[string]struct{}{
"existing": {},
"alpha": {},
"beta": {},
}
if !reflect.DeepEqual(set, want) {
t.Fatalf("expected %#v, got %#v", want, set)
}
}
func TestManagedMetadataAddMethods(t *testing.T) {
t.Parallel()
m := ManagedMetadata{
labels: map[string]struct{}{},
annotations: map[string]struct{}{},
}
m.addLabels("example.corp/label", " example.corp/trimmed-label ", "")
m.addAnnotations("example.corp/annotation", " example.corp/trimmed-annotation ", "")
if !m.HasLabel("example.corp/label") {
t.Fatalf("expected added label")
}
if !m.HasLabel("example.corp/trimmed-label") {
t.Fatalf("expected trimmed added label")
}
if !m.HasAnnotation("example.corp/annotation") {
t.Fatalf("expected added annotation")
}
if !m.HasAnnotation("example.corp/trimmed-annotation") {
t.Fatalf("expected trimmed added annotation")
}
if m.HasLabel("") {
t.Fatalf("empty label must not be added")
}
if m.HasAnnotation("") {
t.Fatalf("empty annotation must not be added")
}
}
func TestManagedMetadataHasAnnotationPrefix(t *testing.T) {
t.Parallel()
m := ManagedMetadata{
annotations: map[string]struct{}{
"example.corp/exact": {},
},
annotationPrefixes: []string{
"example.corp/prefix/",
},
}
tests := []struct {
name string
key string
want bool
}{
{
name: "exact annotation",
key: "example.corp/exact",
want: true,
},
{
name: "prefix annotation",
key: "example.corp/prefix/value",
want: true,
},
{
name: "prefix itself also matches",
key: "example.corp/prefix/",
want: true,
},
{
name: "similar prefix does not match",
key: "example.corp/prefix-other/value",
want: false,
},
{
name: "unknown annotation",
key: "example.corp/unknown",
want: false,
},
{
name: "case sensitive prefix",
key: "Example.Corp/prefix/value",
want: false,
},
{
name: "empty key",
key: "",
want: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
got := m.HasAnnotation(tt.key)
if got != tt.want {
t.Fatalf("expected %t, got %t", tt.want, got)
}
})
}
}
func TestObjectSkipRuleShouldSkip(t *testing.T) {
t.Parallel()
tests := []struct {
name string
rule ObjectSkipRule
labels map[string]string
annotations map[string]string
want bool
}{
{
name: "empty rule does not skip",
rule: ObjectSkipRule{},
want: false,
},
{
name: "matching label skips",
rule: ObjectSkipRule{
Labels: map[string]string{
"managed-by": "controller",
},
},
labels: map[string]string{
"managed-by": "controller",
},
want: true,
},
{
name: "missing label does not skip",
rule: ObjectSkipRule{
Labels: map[string]string{
"managed-by": "controller",
},
},
labels: nil,
want: false,
},
{
name: "non matching label value does not skip",
rule: ObjectSkipRule{
Labels: map[string]string{
"managed-by": "controller",
},
},
labels: map[string]string{
"managed-by": "human",
},
want: false,
},
{
name: "label match is case-sensitive",
rule: ObjectSkipRule{
Labels: map[string]string{
"managed-by": "controller",
},
},
labels: map[string]string{
"managed-by": "Controller",
},
want: false,
},
{
name: "matching annotation skips",
rule: ObjectSkipRule{
Annotations: map[string]string{
"example.corp/skip": "true",
},
},
annotations: map[string]string{
"example.corp/skip": "true",
},
want: true,
},
{
name: "missing annotation does not skip",
rule: ObjectSkipRule{
Annotations: map[string]string{
"example.corp/skip": "true",
},
},
annotations: nil,
want: false,
},
{
name: "non matching annotation value does not skip",
rule: ObjectSkipRule{
Annotations: map[string]string{
"example.corp/skip": "true",
},
},
annotations: map[string]string{
"example.corp/skip": "false",
},
want: false,
},
{
name: "all labels must match",
rule: ObjectSkipRule{
Labels: map[string]string{
"managed-by": "controller",
"owner": "capsule",
},
},
labels: map[string]string{
"managed-by": "controller",
"owner": "other",
},
want: false,
},
{
name: "all annotations must match",
rule: ObjectSkipRule{
Annotations: map[string]string{
"example.corp/skip": "true",
"example.corp/owner": "capsule",
},
},
annotations: map[string]string{
"example.corp/skip": "true",
"example.corp/owner": "other",
},
want: false,
},
{
name: "labels and annotations must both match",
rule: ObjectSkipRule{
Labels: map[string]string{
"managed-by": "controller",
},
Annotations: map[string]string{
"example.corp/skip": "true",
},
},
labels: map[string]string{
"managed-by": "controller",
},
annotations: map[string]string{
"example.corp/skip": "true",
},
want: true,
},
{
name: "matching label but missing required annotation does not skip",
rule: ObjectSkipRule{
Labels: map[string]string{
"managed-by": "controller",
},
Annotations: map[string]string{
"example.corp/skip": "true",
},
},
labels: map[string]string{
"managed-by": "controller",
},
annotations: nil,
want: false,
},
{
name: "missing key must not match empty expected value",
rule: ObjectSkipRule{
Labels: map[string]string{
"empty": "",
},
},
labels: nil,
want: false,
},
{
name: "present empty value matches empty expected value",
rule: ObjectSkipRule{
Labels: map[string]string{
"empty": "",
},
},
labels: map[string]string{
"empty": "",
},
want: true,
},
{
name: "extra labels and annotations do not prevent match",
rule: ObjectSkipRule{
Labels: map[string]string{
"managed-by": "controller",
},
},
labels: map[string]string{
"managed-by": "controller",
"extra": "value",
},
annotations: map[string]string{
"extra": "value",
},
want: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
got := tt.rule.ShouldSkip(tt.labels, tt.annotations)
if got != tt.want {
t.Fatalf("expected %t, got %t", tt.want, got)
}
})
}
}
func TestObjectSkipRuleShouldSkipNilReceiver(t *testing.T) {
t.Parallel()
var rule *ObjectSkipRule
if rule.ShouldSkip(
map[string]string{
"managed-by": "controller",
},
nil,
) {
t.Fatalf("nil rule must not skip")
}
}
func TestDefaultObjectSkipRules(t *testing.T) {
t.Parallel()
rules := DefaultObjectSkipRules()
if len(rules) != 2 {
t.Fatalf("expected three default skip rules, got %d", len(rules))
}
if got := rules[0].Labels[NewManagedByCapsuleLabel]; got != ValueController {
t.Fatalf("expected default skip label %q=%q, got %q", NewManagedByCapsuleLabel, ValueController, got)
}
if got := rules[1].Labels[NewManagedByCapsuleLabel]; got != ValueControllerResources {
t.Fatalf("expected legacy default skip label %q=%q, got %q", NewManagedByCapsuleLabel, ValueControllerResources, got)
}
for _, rule := range rules {
if len(rule.Annotations) != 0 {
t.Fatalf("expected no default skip annotations, got %#v", rule.Annotations)
}
}
}
func TestShouldSkipObjectByRules(t *testing.T) {
t.Parallel()
tests := []struct {
name string
obj *metav1.PartialObjectMetadata
rules []ObjectSkipRule
want bool
}{
{
name: "nil object does not skip",
obj: nil,
rules: DefaultObjectSkipRules(),
want: false,
},
{
name: "nil rules do not skip",
obj: objectWithMetadata(
map[string]string{
NewManagedByCapsuleLabel: ValueController,
},
nil,
),
rules: nil,
want: false,
},
{
name: "empty rules do not skip",
obj: objectWithMetadata(
map[string]string{
NewManagedByCapsuleLabel: ValueController,
},
nil,
),
rules: []ObjectSkipRule{},
want: false,
},
{
name: "default Capsule controller-managed object skips",
obj: objectWithMetadata(
map[string]string{
NewManagedByCapsuleLabel: ValueController,
},
nil,
),
rules: DefaultObjectSkipRules(),
want: true,
},
{
name: "legacy Capsule resources object skips",
obj: objectWithMetadata(
map[string]string{
NewManagedByCapsuleLabel: ValueControllerResources,
},
nil,
),
rules: DefaultObjectSkipRules(),
want: true,
},
{
name: "default skip is case-sensitive",
obj: objectWithMetadata(
map[string]string{
NewManagedByCapsuleLabel: "Controller",
},
nil,
),
rules: DefaultObjectSkipRules(),
want: false,
},
{
name: "plain managed-by controller is not skipped by default",
obj: objectWithMetadata(
map[string]string{
"managed-by": "controller",
},
nil,
),
rules: DefaultObjectSkipRules(),
want: false,
},
{
name: "non matching object does not skip",
obj: objectWithMetadata(
map[string]string{
NewManagedByCapsuleLabel: "human",
},
nil,
),
rules: DefaultObjectSkipRules(),
want: false,
},
{
name: "any matching rule skips",
obj: objectWithMetadata(
map[string]string{
"app": "demo",
},
map[string]string{
"example.corp/skip": "true",
},
),
rules: []ObjectSkipRule{
{
Labels: map[string]string{
"app": "other",
},
},
{
Annotations: map[string]string{
"example.corp/skip": "true",
},
},
},
want: true,
},
{
name: "object without labels and annotations does not skip",
obj: objectWithMetadata(nil, nil),
rules: []ObjectSkipRule{
{
Labels: map[string]string{
"managed-by": "controller",
},
},
},
want: false,
},
{
name: "empty skip rule does not skip object",
obj: objectWithMetadata(
map[string]string{
"app": "demo",
},
nil,
),
rules: []ObjectSkipRule{
{},
},
want: false,
},
{
name: "custom plain managed-by rule skips",
obj: objectWithMetadata(
map[string]string{
"managed-by": "controller",
},
nil,
),
rules: []ObjectSkipRule{
{
Labels: map[string]string{
"managed-by": "controller",
},
},
},
want: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
got := ShouldSkipObjectByRules(tt.obj, tt.rules)
if got != tt.want {
t.Fatalf("expected %t, got %t", tt.want, got)
}
})
}
}
func objectWithMetadata(
labels map[string]string,
annotations map[string]string,
) *metav1.PartialObjectMetadata {
return &metav1.PartialObjectMetadata{
ObjectMeta: metav1.ObjectMeta{
Labels: labels,
Annotations: annotations,
},
}
}