mirror of
https://github.com/projectcapsule/capsule.git
synced 2026-08-19 04:26:45 +00:00
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>
This commit is contained in:
co-authored by
Copilot Autofix powered by AI
parent
6fbd472f27
commit
77d1810bb9
Vendored
+4
-4
@@ -11,7 +11,7 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/projectcapsule/capsule/pkg/api"
|
||||
"github.com/projectcapsule/capsule/pkg/api/runtime"
|
||||
)
|
||||
|
||||
type CompiledRegex struct {
|
||||
@@ -46,7 +46,7 @@ func NewRegexCache() *RegexCache {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *RegexCache) GetOrCompile(expr api.ExpressionRegex) (*CompiledRegex, bool, error) {
|
||||
func (c *RegexCache) GetOrCompile(expr runtime.ExpressionRegex) (*CompiledRegex, bool, error) {
|
||||
if c == nil {
|
||||
return nil, false, fmt.Errorf("regex cache is nil")
|
||||
}
|
||||
@@ -129,7 +129,7 @@ func (c *RegexCache) Reset() {
|
||||
c.re = make(map[string]*CompiledRegex)
|
||||
}
|
||||
|
||||
func (c *RegexCache) MatchRegex(expr api.ExpressionRegex, value string) (bool, error) {
|
||||
func (c *RegexCache) MatchRegex(expr runtime.ExpressionRegex, value string) (bool, error) {
|
||||
compiled, _, err := c.GetOrCompile(expr)
|
||||
if err != nil {
|
||||
return false, err
|
||||
@@ -138,7 +138,7 @@ func (c *RegexCache) MatchRegex(expr api.ExpressionRegex, value string) (bool, e
|
||||
return compiled.MatchString(value), nil
|
||||
}
|
||||
|
||||
func HashRegex(expr api.ExpressionRegex) string {
|
||||
func HashRegex(expr runtime.ExpressionRegex) string {
|
||||
var b strings.Builder
|
||||
|
||||
b.WriteString(strings.TrimSpace(expr.Expression))
|
||||
|
||||
Vendored
+17
-17
@@ -6,7 +6,7 @@ package cache
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/projectcapsule/capsule/pkg/api"
|
||||
"github.com/projectcapsule/capsule/pkg/api/runtime"
|
||||
)
|
||||
|
||||
func TestCompiledRegexMatchString(t *testing.T) {
|
||||
@@ -14,13 +14,13 @@ func TestCompiledRegexMatchString(t *testing.T) {
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
expression api.ExpressionRegex
|
||||
expression runtime.ExpressionRegex
|
||||
value string
|
||||
want bool
|
||||
}{
|
||||
{
|
||||
name: "normal expression matches matching value",
|
||||
expression: api.ExpressionRegex{
|
||||
expression: runtime.ExpressionRegex{
|
||||
Expression: "trusted/.*",
|
||||
},
|
||||
value: "trusted/team/app:1",
|
||||
@@ -28,7 +28,7 @@ func TestCompiledRegexMatchString(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "normal expression does not match non matching value",
|
||||
expression: api.ExpressionRegex{
|
||||
expression: runtime.ExpressionRegex{
|
||||
Expression: "trusted/.*",
|
||||
},
|
||||
value: "docker.io/team/app:1",
|
||||
@@ -36,7 +36,7 @@ func TestCompiledRegexMatchString(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "negated expression does not match matching value",
|
||||
expression: api.ExpressionRegex{
|
||||
expression: runtime.ExpressionRegex{
|
||||
Expression: "trusted/.*",
|
||||
Negate: true,
|
||||
},
|
||||
@@ -45,7 +45,7 @@ func TestCompiledRegexMatchString(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "negated expression matches non matching value",
|
||||
expression: api.ExpressionRegex{
|
||||
expression: runtime.ExpressionRegex{
|
||||
Expression: "trusted/.*",
|
||||
Negate: true,
|
||||
},
|
||||
@@ -79,7 +79,7 @@ func TestRegexCache_GetOrCompile(t *testing.T) {
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
expression api.ExpressionRegex
|
||||
expression runtime.ExpressionRegex
|
||||
value string
|
||||
wantMatch bool
|
||||
wantErr bool
|
||||
@@ -88,7 +88,7 @@ func TestRegexCache_GetOrCompile(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
name: "compile matching regex",
|
||||
expression: api.ExpressionRegex{
|
||||
expression: runtime.ExpressionRegex{
|
||||
Expression: `^ghcr\.io/projectcapsule/.*`,
|
||||
},
|
||||
value: "ghcr.io/projectcapsule/capsule:latest",
|
||||
@@ -99,7 +99,7 @@ func TestRegexCache_GetOrCompile(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "compile non matching regex",
|
||||
expression: api.ExpressionRegex{
|
||||
expression: runtime.ExpressionRegex{
|
||||
Expression: `^ghcr\.io/projectcapsule/.*`,
|
||||
},
|
||||
value: "docker.io/library/nginx:latest",
|
||||
@@ -110,7 +110,7 @@ func TestRegexCache_GetOrCompile(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "compile negated matching regex",
|
||||
expression: api.ExpressionRegex{
|
||||
expression: runtime.ExpressionRegex{
|
||||
Expression: `^ghcr\.io/projectcapsule/.*`,
|
||||
Negate: true,
|
||||
},
|
||||
@@ -122,7 +122,7 @@ func TestRegexCache_GetOrCompile(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "compile negated non matching regex",
|
||||
expression: api.ExpressionRegex{
|
||||
expression: runtime.ExpressionRegex{
|
||||
Expression: `^ghcr\.io/projectcapsule/.*`,
|
||||
Negate: true,
|
||||
},
|
||||
@@ -134,7 +134,7 @@ func TestRegexCache_GetOrCompile(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "reject empty expression",
|
||||
expression: api.ExpressionRegex{
|
||||
expression: runtime.ExpressionRegex{
|
||||
Expression: "",
|
||||
},
|
||||
value: "ghcr.io/projectcapsule/capsule:latest",
|
||||
@@ -143,7 +143,7 @@ func TestRegexCache_GetOrCompile(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "reject invalid regex",
|
||||
expression: api.ExpressionRegex{
|
||||
expression: runtime.ExpressionRegex{
|
||||
Expression: `[`,
|
||||
},
|
||||
value: "ghcr.io/projectcapsule/capsule:latest",
|
||||
@@ -207,7 +207,7 @@ func TestRegexCache_GetOrCompile_ReusesCachedRegex(t *testing.T) {
|
||||
|
||||
c := NewRegexCache()
|
||||
|
||||
expr := api.ExpressionRegex{
|
||||
expr := runtime.ExpressionRegex{
|
||||
Expression: `^ghcr\.io/projectcapsule/.*`,
|
||||
}
|
||||
|
||||
@@ -241,11 +241,11 @@ func TestRegexCache_GetOrCompile_ReusesCachedRegex(t *testing.T) {
|
||||
func TestRegexCache_HashRegex_UsesNegate(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
positive := HashRegex(api.ExpressionRegex{
|
||||
positive := HashRegex(runtime.ExpressionRegex{
|
||||
Expression: `^ghcr\.io/.*`,
|
||||
})
|
||||
|
||||
negative := HashRegex(api.ExpressionRegex{
|
||||
negative := HashRegex(runtime.ExpressionRegex{
|
||||
Expression: `^ghcr\.io/.*`,
|
||||
Negate: true,
|
||||
})
|
||||
@@ -260,7 +260,7 @@ func TestRegexCache_Reset(t *testing.T) {
|
||||
|
||||
c := NewRegexCache()
|
||||
|
||||
compiled, _, err := c.GetOrCompile(api.ExpressionRegex{
|
||||
compiled, _, err := c.GetOrCompile(runtime.ExpressionRegex{
|
||||
Expression: `^ghcr\.io/.*`,
|
||||
})
|
||||
if err != nil {
|
||||
|
||||
Vendored
+2
-2
@@ -13,8 +13,8 @@ import (
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
|
||||
"github.com/projectcapsule/capsule/pkg/api"
|
||||
"github.com/projectcapsule/capsule/pkg/api/rules"
|
||||
"github.com/projectcapsule/capsule/pkg/api/runtime"
|
||||
)
|
||||
|
||||
type RuleSet struct {
|
||||
@@ -23,7 +23,7 @@ type RuleSet struct {
|
||||
}
|
||||
|
||||
type CompiledRule struct {
|
||||
Match api.ExpressionMatch
|
||||
Match runtime.ExpressionMatch
|
||||
|
||||
// RegexID is empty when Match.Expression is empty.
|
||||
RegexID string
|
||||
|
||||
Vendored
+19
-19
@@ -10,8 +10,8 @@ import (
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
|
||||
"github.com/projectcapsule/capsule/pkg/api"
|
||||
"github.com/projectcapsule/capsule/pkg/api/rules"
|
||||
"github.com/projectcapsule/capsule/pkg/api/runtime"
|
||||
)
|
||||
|
||||
func TestNewRegistryRuleSetCache(t *testing.T) {
|
||||
@@ -94,7 +94,7 @@ func TestRegistryRuleSetCacheGetOrBuild(t *testing.T) {
|
||||
{
|
||||
name: "registry with negated expression builds ruleset",
|
||||
rules: []rules.OCIRegistry{
|
||||
registryWithExpression(api.ExpressionRegex{
|
||||
registryWithExpression(runtime.ExpressionRegex{
|
||||
Expression: "trusted/.*",
|
||||
Negate: true,
|
||||
}),
|
||||
@@ -242,7 +242,7 @@ func TestRegistryRuleSetCacheBuildRuleSet(t *testing.T) {
|
||||
specRules := []rules.OCIRegistry{
|
||||
registry("harbor/.*"),
|
||||
registryWithPolicy("ghcr.io/.*", corev1.PullAlways, corev1.PullIfNotPresent),
|
||||
registryWithExpression(api.ExpressionRegex{
|
||||
registryWithExpression(runtime.ExpressionRegex{
|
||||
Expression: "trusted/.*",
|
||||
Negate: true,
|
||||
}),
|
||||
@@ -363,7 +363,7 @@ func TestRegistryRuleSetCacheMatchReference(t *testing.T) {
|
||||
{
|
||||
name: "negated expression matches non-matching reference",
|
||||
rules: []rules.OCIRegistry{
|
||||
registryWithExpression(api.ExpressionRegex{
|
||||
registryWithExpression(runtime.ExpressionRegex{
|
||||
Expression: "trusted/.*",
|
||||
Negate: true,
|
||||
}),
|
||||
@@ -377,7 +377,7 @@ func TestRegistryRuleSetCacheMatchReference(t *testing.T) {
|
||||
{
|
||||
name: "negated expression does not match matching reference",
|
||||
rules: []rules.OCIRegistry{
|
||||
registryWithExpression(api.ExpressionRegex{
|
||||
registryWithExpression(runtime.ExpressionRegex{
|
||||
Expression: "trusted/.*",
|
||||
Negate: true,
|
||||
}),
|
||||
@@ -406,7 +406,7 @@ func TestRegistryRuleSetCacheMatchReference(t *testing.T) {
|
||||
{
|
||||
name: "nested regex expression wins over legacy url",
|
||||
rules: []rules.OCIRegistry{
|
||||
registryWithExpression(api.ExpressionRegex{
|
||||
registryWithExpression(runtime.ExpressionRegex{
|
||||
Expression: "nested/.*",
|
||||
}),
|
||||
},
|
||||
@@ -417,7 +417,7 @@ func TestRegistryRuleSetCacheMatchReference(t *testing.T) {
|
||||
{
|
||||
name: "legacy url is ignored when nested regex expression is set",
|
||||
rules: []rules.OCIRegistry{
|
||||
registryWithExpression(api.ExpressionRegex{
|
||||
registryWithExpression(runtime.ExpressionRegex{
|
||||
Expression: "nested/.*",
|
||||
}),
|
||||
},
|
||||
@@ -526,7 +526,7 @@ func TestRegistryRuleSetCacheMatchRuleSetWithPullPolicy(t *testing.T) {
|
||||
{
|
||||
name: "negated expression respects pull policy",
|
||||
rules: []rules.OCIRegistry{
|
||||
registryWithExpressionAndPolicy(api.ExpressionRegex{
|
||||
registryWithExpressionAndPolicy(runtime.ExpressionRegex{
|
||||
Expression: "trusted/.*",
|
||||
Negate: true,
|
||||
}, corev1.PullIfNotPresent),
|
||||
@@ -541,7 +541,7 @@ func TestRegistryRuleSetCacheMatchRuleSetWithPullPolicy(t *testing.T) {
|
||||
{
|
||||
name: "negated expression still rejects forbidden pull policy",
|
||||
rules: []rules.OCIRegistry{
|
||||
registryWithExpressionAndPolicy(api.ExpressionRegex{
|
||||
registryWithExpressionAndPolicy(runtime.ExpressionRegex{
|
||||
Expression: "trusted/.*",
|
||||
Negate: true,
|
||||
}, corev1.PullNever),
|
||||
@@ -714,14 +714,14 @@ func TestRegistryRuleSetCacheHashRules(t *testing.T) {
|
||||
c := NewRegistryRuleSetCache(nil)
|
||||
|
||||
hashA := c.HashRules([]rules.OCIRegistry{
|
||||
registryWithExpression(api.ExpressionRegex{
|
||||
registryWithExpression(runtime.ExpressionRegex{
|
||||
Expression: "trusted/.*",
|
||||
Negate: false,
|
||||
}),
|
||||
})
|
||||
|
||||
hashB := c.HashRules([]rules.OCIRegistry{
|
||||
registryWithExpression(api.ExpressionRegex{
|
||||
registryWithExpression(runtime.ExpressionRegex{
|
||||
Expression: "trusted/.*",
|
||||
Negate: true,
|
||||
}),
|
||||
@@ -924,8 +924,8 @@ func TestRegistryRuleSetCacheInsertForTest(t *testing.T) {
|
||||
|
||||
func registry(expression string) rules.OCIRegistry {
|
||||
return rules.OCIRegistry{
|
||||
ExpressionMatch: api.ExpressionMatch{
|
||||
ExpressionRegex: api.ExpressionRegex{
|
||||
ExpressionMatch: runtime.ExpressionMatch{
|
||||
ExpressionRegex: runtime.ExpressionRegex{
|
||||
Expression: expression,
|
||||
Negate: false,
|
||||
},
|
||||
@@ -935,8 +935,8 @@ func registry(expression string) rules.OCIRegistry {
|
||||
|
||||
func registryWithPolicy(expression string, policies ...corev1.PullPolicy) rules.OCIRegistry {
|
||||
return rules.OCIRegistry{
|
||||
ExpressionMatch: api.ExpressionMatch{
|
||||
ExpressionRegex: api.ExpressionRegex{
|
||||
ExpressionMatch: runtime.ExpressionMatch{
|
||||
ExpressionRegex: runtime.ExpressionRegex{
|
||||
Expression: expression,
|
||||
Negate: false,
|
||||
},
|
||||
@@ -945,20 +945,20 @@ func registryWithPolicy(expression string, policies ...corev1.PullPolicy) rules.
|
||||
}
|
||||
}
|
||||
|
||||
func registryWithExpression(expression api.ExpressionRegex) rules.OCIRegistry {
|
||||
func registryWithExpression(expression runtime.ExpressionRegex) rules.OCIRegistry {
|
||||
return rules.OCIRegistry{
|
||||
ExpressionMatch: api.ExpressionMatch{
|
||||
ExpressionMatch: runtime.ExpressionMatch{
|
||||
ExpressionRegex: expression,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func registryWithExpressionAndPolicy(
|
||||
expression api.ExpressionRegex,
|
||||
expression runtime.ExpressionRegex,
|
||||
policies ...corev1.PullPolicy,
|
||||
) rules.OCIRegistry {
|
||||
return rules.OCIRegistry{
|
||||
ExpressionMatch: api.ExpressionMatch{
|
||||
ExpressionMatch: runtime.ExpressionMatch{
|
||||
ExpressionRegex: expression,
|
||||
},
|
||||
Policy: policies,
|
||||
|
||||
Reference in New Issue
Block a user