diff --git a/charts/apl-network-policies/templates/networkpolicies/harbor-db.yaml b/charts/apl-network-policies/templates/networkpolicies/harbor-db.yaml new file mode 100644 index 0000000000..7a02e43b9a --- /dev/null +++ b/charts/apl-network-policies/templates/networkpolicies/harbor-db.yaml @@ -0,0 +1,47 @@ +{{- if .Values.netpols.harborDb }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: harbor-db-platform-policy + namespace: harbor + labels: + {{- include "apl-network-policies.labels" . | nindent 4 }} + app: harbor +spec: + # Scoped to the Harbor CloudNativePG instances rather than the whole harbor namespace: Harbor has + # a wide component surface (core, jobservice, registry, trivy, exporter, redis) and a + # namespace-wide Ingress policy would have to enumerate all of it correctly or take the registry + # down. The database is where the documented default-deny gap actually is. + podSelector: + matchLabels: + cnpg.io/cluster: harbor-otomi-db + policyTypes: + - Ingress + ingress: + # Allow the CloudNativePG operator to poll instance status (8000) and metrics (9187). + # Without this the operator cannot read instance status, the Harbor Postgres replica never + # starts, and the stack stalls on Instance Status Extraction Error → ClusterIsNotReady → + # Degraded — with nothing in the symptom pointing at a NetworkPolicy. + - from: + - namespaceSelector: + matchLabels: + name: cnpg-system + # Allow the Harbor components (core, jobservice, registry, exporter, trivy) to reach Postgres, + # and the instances to reach each other for replication. + - from: + - namespaceSelector: + matchLabels: + name: harbor + # Allow monitoring access + - from: + - namespaceSelector: + matchLabels: + name: monitoring + podSelector: + matchLabels: + app.kubernetes.io/instance: po-prometheus + ports: + - protocol: TCP + port: 9187 +{{- end }} diff --git a/charts/apl-network-policies/values.yaml b/charts/apl-network-policies/values.yaml index 7c0f0a7adb..d12df3a02e 100644 --- a/charts/apl-network-policies/values.yaml +++ b/charts/apl-network-policies/values.yaml @@ -32,5 +32,14 @@ # * Monitoring namespace (for metrics scraping) # * Internal otomi namespace communication # +# For harbor (netpols.harborDb: true): +# - Creates a NetworkPolicy in the harbor namespace, scoped to the CloudNativePG instances of +# harbor-otomi-db (not the whole namespace — Harbor's component surface is wide) +# - Allows ingress from: +# * cnpg-system (operator polling instance status on 8000 and metrics on 9187) +# * the harbor namespace (components reaching Postgres; instances replicating to each other) +# * Monitoring namespace on 9187 (for metrics scraping) +# - Only rendered when harbor is enabled +# # The complex network policy rules are baked into the chart templates, # so users only need to toggle network policies on/off per application. diff --git a/helmfile.d/snippets/defaults.yaml b/helmfile.d/snippets/defaults.yaml index 7d9d569960..b8f3683fc0 100644 --- a/helmfile.d/snippets/defaults.yaml +++ b/helmfile.d/snippets/defaults.yaml @@ -199,6 +199,8 @@ environments: _rawValues: {} harbor: enabled: false + networkPolicies: + enabled: false oidcAutoOnboard: true oidcUserClaim: email registry: diff --git a/values-schema.yaml b/values-schema.yaml index 9502538c98..c939df5a3f 100644 --- a/values-schema.yaml +++ b/values-schema.yaml @@ -1690,6 +1690,8 @@ properties: properties: _rawValues: $ref: '#/definitions/rawValues' + networkPolicies: + $ref: '#/definitions/appNetworkPolicyConfig' enabled: type: boolean default: true diff --git a/values/apl-network-policies/apl-network-policies.gotmpl b/values/apl-network-policies/apl-network-policies.gotmpl index cb3798134e..d5a54f043e 100644 --- a/values/apl-network-policies/apl-network-policies.gotmpl +++ b/values/apl-network-policies/apl-network-policies.gotmpl @@ -1,12 +1,14 @@ {{- $v := .Values }} {{- $a := $v.apps }} {{- $oa := $v.apps | get "otomi-api" }} +{{- $h := $v.apps | get "harbor" }} # Simple per-app network policy configuration netpols: gitServer: {{ not ($a | get "git-server.enabled") }} gitea: {{ $a.gitea.networkPolicies.enabled}} otomiApi: {{ $oa.networkPolicies.enabled}} + harborDb: {{ and ($h.networkPolicies.enabled) ($h.enabled) }} ingressGatewaySelectors: - namespaceSelector: