diff --git a/cluster/manifests/01-admission-control/host-policy.yaml b/cluster/manifests/01-admission-control/host-policy.yaml new file mode 100644 index 0000000000..0a16364d59 --- /dev/null +++ b/cluster/manifests/01-admission-control/host-policy.yaml @@ -0,0 +1,93 @@ +# {{ $hosted_zone_parent_domain := slice (split .Values.hosted_zone ".") 1 | join "." }} + +# {{ if eq .Cluster.ConfigItems.ingresses_validation "enabled" }} +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingAdmissionPolicy +metadata: + name: ingress-host-policy.teapot.zalan.do + annotations: + kubernetes.io/description: | + Validates that Ingress hosts from {{ $hosted_zone_parent_domain }} domain are in {{ .Values.hosted_zone }} domain. +spec: + failurePolicy: Fail + matchConstraints: + resourceRules: + - apiGroups: ["networking.k8s.io"] + apiVersions: ["v1"] + operations: ["CREATE", "UPDATE"] + resources: ["ingresses"] + matchConditions: + # exclude owned resources, e.g. created by StackSet and FabricGateway controllers. + - name: exclude-owned-resources + expression: | + !has(object.metadata.ownerReferences) + validations: + - expression: | + object.spec.rules + .map(r, r.host) + .filter(h, h.endsWith(".{{ $hosted_zone_parent_domain }}")) + .all(h, h.endsWith(".{{ .Values.hosted_zone }}")) + reason: Invalid + # show the first invalid host in the error message + messageExpression: | + "Ingress host must be in {{ .Values.hosted_zone }} domain but " + + object.spec.rules + .map(r, r.host) + .filter(h, h.endsWith(".{{ $hosted_zone_parent_domain }}")) + .filter(h, !h.endsWith(".{{ .Values.hosted_zone }}"))[0] + + " found" +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingAdmissionPolicyBinding +metadata: + name: ingress-host-policy-binding.teapot.zalan.do +spec: + policyName: ingress-host-policy.teapot.zalan.do + validationActions: [Deny] +# {{ end }} + +# {{ if eq .Cluster.ConfigItems.routegroups_validation "enabled" }} +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingAdmissionPolicy +metadata: + name: routegroup-host-policy.teapot.zalan.do + annotations: + kubernetes.io/description: | + Validates that RouteGroup hosts from {{ $hosted_zone_parent_domain }} domain are in {{ .Values.hosted_zone }} domain. +spec: + failurePolicy: Fail + matchConstraints: + resourceRules: + - apiGroups: ["zalando.org"] + apiVersions: ["v1"] + operations: ["CREATE", "UPDATE"] + resources: ["routegroups"] + matchConditions: + # exclude owned resources, e.g. created by StackSet and FabricGateway controllers. + - name: exclude-owned-resources + expression: | + !has(object.metadata.ownerReferences) + validations: + - expression: | + object.spec.hosts + .filter(h, h.endsWith(".{{ $hosted_zone_parent_domain }}")) + .all(h, h.endsWith(".{{ .Values.hosted_zone }}")) + reason: Invalid + # show the first invalid host in the error message + messageExpression: | + "RouteGroup host must be in {{ .Values.hosted_zone }} domain but " + + object.spec.hosts + .filter(h, h.endsWith(".{{ $hosted_zone_parent_domain }}")) + .filter(h, !h.endsWith(".{{ .Values.hosted_zone }}"))[0] + + " found" +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingAdmissionPolicyBinding +metadata: + name: routegroup-host-policy-binding.teapot.zalan.do +spec: + policyName: routegroup-host-policy.teapot.zalan.do + validationActions: [Deny] +# {{ end }} diff --git a/cluster/manifests/deletions.yaml b/cluster/manifests/deletions.yaml index 401057c9a8..980817f66d 100644 --- a/cluster/manifests/deletions.yaml +++ b/cluster/manifests/deletions.yaml @@ -320,3 +320,17 @@ post_apply: kind: Service namespace: kube-system {{- end }} + +# {{ if ne .Cluster.ConfigItems.ingresses_validation "enabled" }} +- kind: ValidatingAdmissionPolicyBinding + name: ingress-host-policy-binding.teapot.zalan.do +- kind: ValidatingAdmissionPolicy + name: ingress-host-policy.teapot.zalan.do +# {{ end }} + +# {{ if ne .Cluster.ConfigItems.routegroups_validation "enabled" }} +- kind: ValidatingAdmissionPolicyBinding + name: routegroup-host-policy-binding.teapot.zalan.do +- kind: ValidatingAdmissionPolicy + name: routegroup-host-policy.teapot.zalan.do +# {{ end }}