Skip to content

Commit 267ea51

Browse files
committed
fix(cozystack-basics): gate the hostname VAP policies on the VAP API
Render the route, gateway and ingress hostname ValidatingAdmissionPolicies only where the admissionregistration.k8s.io/v1/ValidatingAdmissionPolicy API is served, matching the deletion-protection guard, so a cluster without that API does not receive an unrenderable resource. Assisted-By: Claude <[email protected]> Signed-off-by: Aleksei Sviridkin <[email protected]>
1 parent 18e459a commit 267ea51

7 files changed

Lines changed: 59 additions & 1 deletion

‎packages/system/cozystack-basics/templates/gateway-hostname-policy.yaml‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
{{- /* Render only where the ValidatingAdmissionPolicy API is served (GA since Kubernetes 1.30; the management cluster requires 1.33+). Same guard as packages/core/platform/templates/deletion-protection.yaml. */}}
2+
{{- if .Capabilities.APIVersions.Has "admissionregistration.k8s.io/v1/ValidatingAdmissionPolicy" }}
13
---
24
apiVersion: admissionregistration.k8s.io/v1
35
kind: ValidatingAdmissionPolicy
@@ -154,3 +156,4 @@ metadata:
154156
spec:
155157
policyName: cozystack-namespace-host-label-policy
156158
validationActions: [Deny]
159+
{{- end }}

‎packages/system/cozystack-basics/templates/ingress-hostname-policy.yaml‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@
5757
labelling yet — in which case the caller should retry.
5858
*/}}
5959
{{- $rootHost := index .Values._cluster "root-host" }}
60-
{{- if $rootHost }}
60+
{{- /* Also gate on the ValidatingAdmissionPolicy API (GA since Kubernetes 1.30; the management cluster requires 1.33+), so a cluster without it does not get an unrenderable resource. Same guard as packages/core/platform/templates/deletion-protection.yaml. */}}
61+
{{- if and $rootHost (.Capabilities.APIVersions.Has "admissionregistration.k8s.io/v1/ValidatingAdmissionPolicy") }}
6162
{{- $A := `namespaceObject.metadata.labels["namespace.cozystack.io/host"]` }}
6263
{{- $celValidator := printf `(namespaceObject == null || !has(namespaceObject.metadata.labels) || !("namespace.cozystack.io/host" in namespaceObject.metadata.labels)) ? false : (!has(object.spec.defaultBackend) && (!has(object.spec.rules) || object.spec.rules.all(r, has(r.host) && r.host != "" && (r.host == %s || r.host.endsWith("." + %s) || (!r.host.startsWith("*.") && !(r.host == %q || r.host.endsWith(%q)))))) && (!has(object.spec.tls) || object.spec.tls.all(t, !has(t.hosts) || t.hosts.all(h, h != "" && (h == %s || h.endsWith("." + %s) || (!h.startsWith("*.") && !(h == %q || h.endsWith(%q))))))))` $A $A $rootHost (printf ".%s" $rootHost) $A $A $rootHost (printf ".%s" $rootHost) -}}
6364
---

‎packages/system/cozystack-basics/templates/route-hostname-policy.yaml‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
finished labelling yet — in which case the caller should retry.
3737
*/}}
3838
{{- $celValidator := `(namespaceObject == null || !has(namespaceObject.metadata.labels) || !("namespace.cozystack.io/host" in namespaceObject.metadata.labels)) ? false : (!has(object.spec.hostnames) || object.spec.hostnames.all(h, h == namespaceObject.metadata.labels["namespace.cozystack.io/host"] || h.endsWith("." + namespaceObject.metadata.labels["namespace.cozystack.io/host"])))` -}}
39+
{{- /* Render only where the ValidatingAdmissionPolicy API is served (GA since Kubernetes 1.30; the management cluster requires 1.33+). Same guard as packages/core/platform/templates/deletion-protection.yaml. */}}
40+
{{- if .Capabilities.APIVersions.Has "admissionregistration.k8s.io/v1/ValidatingAdmissionPolicy" }}
3941
---
4042
apiVersion: admissionregistration.k8s.io/v1
4143
kind: ValidatingAdmissionPolicy
@@ -104,3 +106,4 @@ metadata:
104106
spec:
105107
policyName: cozystack-route-hostname-policy-tls
106108
validationActions: [Deny]
109+
{{- end }}

‎packages/system/cozystack-basics/tests/gateway-hostname-policy_test.yaml‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@ release:
1919
# Both gates are dropped; inheritance now flows via the label
2020
# selector on Gateway.spec.listeners[].allowedRoutes.
2121

22+
# The template now gates on the ValidatingAdmissionPolicy API (GA since
23+
# Kubernetes 1.30); helm-unittest's default capability set omits it, so every
24+
# rendering test declares it, exactly as the platform deletion-protection suite.
25+
capabilities:
26+
apiVersions:
27+
- admissionregistration.k8s.io/v1/ValidatingAdmissionPolicy
28+
2229
tests:
2330
- it: renders 3 VAPs + 3 Bindings (6 documents total)
2431
asserts:
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
suite: cozystack-basics hostname VAP policies are gated on the ValidatingAdmissionPolicy API
2+
templates:
3+
- templates/route-hostname-policy.yaml
4+
- templates/gateway-hostname-policy.yaml
5+
- templates/ingress-hostname-policy.yaml
6+
release:
7+
name: cozystack-basics
8+
namespace: cozy-system
9+
# root-host is set so the ingress policy's own value gate passes; with it set,
10+
# the only reason any of these three templates render nothing is the missing
11+
# ValidatingAdmissionPolicy API declared below. helm-unittest's per-test
12+
# capabilities merge rather than replace the suite's, so the absent case is a
13+
# separate suite pinned at suite level (mirrors the platform notes gate suite).
14+
set:
15+
_cluster:
16+
root-host: example.org
17+
capabilities:
18+
apiVersions: []
19+
tests:
20+
- it: none of the hostname VAP policies render when the API is unavailable
21+
asserts:
22+
- hasDocuments:
23+
count: 0
24+
template: templates/route-hostname-policy.yaml
25+
- hasDocuments:
26+
count: 0
27+
template: templates/gateway-hostname-policy.yaml
28+
- hasDocuments:
29+
count: 0
30+
template: templates/ingress-hostname-policy.yaml

‎packages/system/cozystack-basics/tests/ingress-hostname-policy_test.yaml‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,13 @@ set:
1313
_cluster:
1414
root-host: example.org
1515

16+
# The template now also gates on the ValidatingAdmissionPolicy API (GA since
17+
# Kubernetes 1.30); helm-unittest's default capability set omits it, so every
18+
# rendering test declares it, exactly as the platform deletion-protection suite.
19+
capabilities:
20+
apiVersions:
21+
- admissionregistration.k8s.io/v1/ValidatingAdmissionPolicy
22+
1623
tests:
1724
- it: renders ValidatingAdmissionPolicy + Binding for legacy Ingress
1825
# Legacy Ingress (networking.k8s.io/v1) is the default ingress path

‎packages/system/cozystack-basics/tests/route-hostname-policy_test.yaml‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@ release:
66
name: cozystack-basics
77
namespace: cozy-system
88

9+
# The template now gates on the ValidatingAdmissionPolicy API (GA since
10+
# Kubernetes 1.30); helm-unittest's default capability set omits it, so every
11+
# rendering test declares it, exactly as the platform deletion-protection suite.
12+
capabilities:
13+
apiVersions:
14+
- admissionregistration.k8s.io/v1/ValidatingAdmissionPolicy
15+
916
tests:
1017
- it: renders ValidatingAdmissionPolicy + Binding for HTTPRoute and TLSRoute (Layer 7)
1118
# Layer 7 (route-hostname VAP) is the only VAP rendered by THIS

0 commit comments

Comments
 (0)