Files
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

87 lines
2.3 KiB
Go

// Copyright 2020-2026 Project Capsule Authors
// SPDX-License-Identifier: Apache-2.0
package validation
import (
"fmt"
"strings"
corev1 "k8s.io/api/core/v1"
apirules "github.com/projectcapsule/capsule/pkg/api/rules"
"github.com/projectcapsule/capsule/pkg/api/runtime"
ruleengine "github.com/projectcapsule/capsule/pkg/ruleengine"
"github.com/projectcapsule/capsule/pkg/runtime/events"
)
func (h *serviceRules) validateExternalNames(
svc *corev1.Service,
enforceBodies []*apirules.NamespaceRuleEnforceBody,
) (*ruleengine.Evaluation, error) {
if svc == nil || svc.Spec.Type != corev1.ServiceTypeExternalName {
return nil, nil
}
if strings.TrimSpace(svc.Spec.ExternalName) == "" {
return nil, nil
}
return evaluateServiceRules[runtime.ExpressionMatch](
svc,
enforceBodies,
serviceRuleSet[runtime.ExpressionMatch]{
Name: "externalName hostname",
EventReason: events.ReasonForbiddenExternalName,
Values: func(svc *corev1.Service) []ruleengine.Value {
return []ruleengine.Value{
{
Value: strings.TrimSpace(svc.Spec.ExternalName),
Path: "spec.externalName",
},
}
},
Rules: func(enforce *apirules.NamespaceRuleEnforceBody) []runtime.ExpressionMatch {
if enforce == nil || enforce.Services.ExternalNames == nil {
return nil
}
return enforce.Services.ExternalNames.Hostnames
},
Matches: func(match runtime.ExpressionMatch, value ruleengine.Value) (ruleengine.Match, error) {
matched, err := match.MatchesWithExpressionMatcher(h.regexCache, value.Value)
if err != nil {
return ruleengine.Match{}, err
}
out := ruleengine.Match{
Matched: matched,
MatchedValue: describeExpressionMatch(match),
}
if matched {
out.Detail = fmt.Sprintf("%q matched hostname rule %s", value.Value, describeExpressionMatch(match))
}
return out, nil
},
RuleDescription: describeExpressionMatch,
AllowedDescription: "Allowed hostnames",
},
)
}
func describeExpressionMatch(match runtime.ExpressionMatch) string {
parts := make([]string, 0, 2)
if len(match.Exact) > 0 {
parts = append(parts, fmt.Sprintf("exact: %s", strings.Join(match.Exact, ", ")))
}
if match.Expression != "" {
parts = append(parts, fmt.Sprintf("exp: %s", match.Expression))
}
return strings.Join(parts, "; ")
}