Skip to content

feat(rules): add service enforcement rules#1982

Merged
oliverbaehler merged 30 commits into
projectcapsule:mainfrom
oliverbaehler:feat/service-rules
Jun 24, 2026
Merged

feat(rules): add service enforcement rules#1982
oliverbaehler merged 30 commits into
projectcapsule:mainfrom
oliverbaehler:feat/service-rules

Conversation

@oliverbaehler

Copy link
Copy Markdown
Collaborator

No description provided.

oliverbaehler and others added 27 commits December 10, 2025 06:50
Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>
Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>
Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>
Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>
Signed-off-by: Oliver Baehler <oliver@sudo-i.net>
Signed-off-by: Oliver Baehler <oliver@sudo-i.net>
Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces service-focused Namespace Rule enforcement (types, LoadBalancer CIDRs, ExternalName hostnames, NodePort ranges) and associated validation, expanding the existing rule engine so Service admissions can be evaluated and reported consistently (including improved “allowed list” messaging). It also adds RuleStatus rule validation plumbing and updates controller runtime configuration options and Helm chart values/templates to support the new webhook and rule fields.

Changes:

  • Add enforce.services API types + deep-copy support, plus rule-body validation for services/workloads.
  • Add Service admission rule evaluators (service type, LoadBalancer CIDRs, ExternalName hostnames, NodePort ranges) and extend evaluator messaging to include rule descriptions/details.
  • Update controller/webhook wiring, Helm chart values/schema/templates, and developer tooling (make test via gotestsum) to support the feature rollout.

Reviewed changes

Copilot reviewed 60 out of 60 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
pkg/runtime/events/reasons.go Add new service-related event reasons.
pkg/ruleengine/validate.go New ruleset body validation logic.
pkg/ruleengine/validate_test.go Unit tests for rule-body validation.
pkg/ruleengine/enforce_evaluator.go Add richer decision context/messaging.
pkg/ruleengine/convert_test.go Tests for extracting enforce bodies.
pkg/api/rules/zz_generated.deepcopy.go DeepCopy updates for new fields/types.
pkg/api/rules/enforce_types.go Add Services enforcement block.
pkg/api/rules/enforce_services_types.go New API types for service enforcement.
pkg/api/forbidden_list.go Fix exact-match implementation (slices.Contains).
pkg/api/forbidden_list_test.go Add regression tests for exact-match.
Makefile Switch make test to gotestsum.
internal/webhook/tenant/validation/rule_validator.go Delegate rule validation to ruleengine validator.
internal/webhook/service/validating.go Update handler type to accept ruleset.
internal/webhook/service/handler.go Use tenant+ruleset typed handler wrapper.
internal/webhook/rules/utils.go Shared expression match description helper.
internal/webhook/rules/status/validation.go New RuleStatus validating webhook handler.
internal/webhook/rules/services/validation/utils.go Shared helpers for service rule checks.
internal/webhook/rules/services/validation/utils_test.go Unit tests for service helpers.
internal/webhook/rules/services/validation/service_type.go Enforce allowed Service types.
internal/webhook/rules/services/validation/service_type_test.go Tests for service type enforcement.
internal/webhook/rules/services/validation/node_port.go Enforce NodePort range rules.
internal/webhook/rules/services/validation/node_port_test.go Tests for NodePort enforcement.
internal/webhook/rules/services/validation/loadbalancer.go Enforce LoadBalancer CIDR constraints.
internal/webhook/rules/services/validation/loadbalancer_test.go Tests for LoadBalancer CIDR enforcement.
internal/webhook/rules/services/validation/factory.go Service rules handler factory + evaluation loop.
internal/webhook/rules/services/validation/factory_test.go Test helper for service rules.
internal/webhook/rules/services/validation/external_name.go Enforce ExternalName hostname rules.
internal/webhook/rules/services/validation/external_name_test.go Tests for ExternalName enforcement.
internal/webhook/rules/pods/validation/schedulers.go Add rule descriptions/allowed label to messages.
internal/webhook/rules/pods/validation/schedulers_test.go Update/add scheduler rule tests.
internal/webhook/rules/pods/validation/registry.go Add registry rule descriptions/allowed label.
internal/webhook/rules/pods/validation/qos.go Add QoS rule descriptions/allowed label.
internal/webhook/rules/pods/validation/qos_test.go Add/update QoS rule tests.
internal/webhook/rules/pods/validation/factory_test.go Test helper for pod rules.
internal/webhook/route/rules.go New route for RuleStatus validating webhook.
internal/controllers/utils/options.go Add runtime controller options + conversion helper.
internal/controllers/tenantowner/manager.go Apply unified controller options helper.
internal/controllers/tenant/manager.go Apply unified controller options helper.
internal/controllers/rulestatus/manager.go Use DeepCopy + unified controller options.
internal/controllers/resources/namespaced.go Apply unified controller options helper.
internal/controllers/resources/global.go Apply unified controller options helper.
internal/controllers/resourcepools/pool_controller.go Apply unified controller options helper.
internal/controllers/resourcepools/claim_controller.go Apply unified controller options helper.
internal/controllers/pv/controller.go Apply unified controller options helper.
internal/controllers/customquotas/global_custom_quota_controller.go Apply unified controller options helper.
internal/controllers/customquotas/custom_quota_controller.go Apply unified controller options helper.
internal/controllers/admission/validating.go Apply unified controller options helper.
internal/controllers/admission/mutating.go Apply unified controller options helper.
hack/distro/capsule/example-setup/tenants.yaml Update example tenant rules with service enforcement.
e2e/namespace_metadata_controller_test.go Rename tenant used in e2e test.
cmd/controller/main.go Add cache sync timeout flag; register service rules handler.
charts/capsule/values.yaml Add rulestatus webhook values.
charts/capsule/values.schema.json Add rulestatus webhook schema.
charts/capsule/templates/configuration.yaml Render rulestatus validating webhook config.
charts/capsule/README.md Document new rulestatus webhook values.
charts/capsule/crds/capsule.clastix.io_tenants.yaml CRD schema for enforce.services.
charts/capsule/crds/capsule.clastix.io_rulestatuses.yaml CRD schema for enforce.services.
Comments suppressed due to low confidence (1)

internal/webhook/tenant/validation/rule_validator.go:86

  • Tenant rule validation no longer verifies that rule.NamespaceSelector is syntactically valid (metav1.LabelSelectorAsSelector). Invalid selectors can now be admitted and will later fail during ruleset evaluation/selection with harder-to-trace errors.

Comment thread cmd/controller/main.go
servicerules.ServiceRules(regexCache),
service.Validating(),
),
),
Comment on lines +74 to +79
func describeExpressionMatch(match api.ExpressionMatch) string {
parts := make([]string, 0, 2)

if len(match.Exact) > 0 {
parts = append(parts, fmt.Sprintf("exact: %s", strings.Join(match.Exact, ", ")))
}
Signed-off-by: Oliver Baehler <oliver@sudo-i.net>
Signed-off-by: Oliver Baehler <oliver@sudo-i.net>
Copilot AI review requested due to automatic review settings June 24, 2026 08:03

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 63 out of 63 changed files in this pull request and generated 3 comments.

Comments suppressed due to low confidence (1)

internal/webhook/tenant/validation/rule_validator.go:86

  • This webhook no longer validates rule.NamespaceSelector values. That means a Tenant can be admitted with an invalid selector, but later pkg/tenant.BuildNamespaceRuleBodyStatus will error at runtime when evaluating rules. Consider reinstating selector compilation validation (e.g., metav1.LabelSelectorAsSelector) and returning a rules[i].namespaceSelector is invalid admission error.

Comment on lines +271 to +278
for i := range limit {
description := describeRule(set, rules[i])
if description == "" {
continue
}

parts = append(parts, description)
}
Comment on lines +74 to +86
func describeExpressionMatch(match api.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, "; ")
}

// Negative control: a key the admin did NOT deny is correctly allowed,
// proving the webhook is not simply denying everything.
func TestPoC_NegativeControl_BenignAllowed(t *testing.T) {
Signed-off-by: Oliver Baehler <oliver@sudo-i.net>
@oliverbaehler oliverbaehler merged commit 755cef5 into projectcapsule:main Jun 24, 2026
19 of 23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants