{{- /*
NetworkPolicy — locks the Harbor pods (core / portal / registry /
jobservice / trivy) down to the minimum egress / ingress required.

Egress targets:
  - Cluster DNS (kube-system) — service discovery for CNPG / Keycloak.
  - bp-cnpg cluster (registry metadata DB) on port 5432.
  - Cloud-native S3 endpoint (Hetzner Object Storage / AWS S3 / etc.)
    on HTTPS/443 — registry blob backend per ADR-0001 §13.
  - Keycloak (when ssoEnabled) on port 8080 — OIDC discovery.
  - HTTPS to upstream registries (when pullMirror.enabled) — replication
    pulls from ghcr.io / docker.io / quay.io etc.

Ingress is locked to:
  - Cilium ingress controller for the Harbor portal/core endpoint.
  - Prometheus scraping when serviceMonitor toggles are on.

DEFAULT FALSE per Catalyst overlay convention — operator turns this on
via per-Sovereign overlay once consumer namespaces / cold-tier endpoints
are known. Per docs/INVIOLABLE-PRINCIPLES.md #4 every selector / port is
operator-tunable through `harborOverlay.networkPolicy.*`.
*/}}
{{- if .Values.harborOverlay.networkPolicy.enabled }}
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: bp-harbor
  namespace: {{ .Release.Namespace }}
  labels:
    {{- include "bp-harbor.labels" . | nindent 4 }}
spec:
  podSelector:
    matchLabels:
      app.kubernetes.io/name: harbor
  policyTypes:
    - Ingress
    - Egress
  ingress:
    # Intra-namespace traffic between Harbor components.
    - from:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: {{ .Release.Namespace }}
    # Ingress controller (Cilium gateway) — terminates the public Harbor
    # endpoint and proxies to harbor-core / harbor-portal.
    - from:
        - namespaceSelector: {}
          podSelector:
            matchLabels:
              app.kubernetes.io/name: cilium
    # Cross-namespace pulls — every namespace running a Catalyst pod
    # may pull images from Harbor.
    - from:
        - namespaceSelector: {}
      ports:
        - protocol: TCP
          port: 80
        - protocol: TCP
          port: 443
        - protocol: TCP
          port: 5000
    # Prometheus scraping when metrics + serviceMonitor are enabled.
    {{- if .Values.harbor.metrics.enabled }}
    - from:
        - namespaceSelector: {}
          podSelector:
            matchLabels:
              app.kubernetes.io/name: prometheus
      ports:
        - protocol: TCP
          port: {{ .Values.harbor.metrics.core.port | default 8001 }}
    {{- end }}
  egress:
    # Cluster DNS — Harbor resolves CNPG, SeaweedFS, Keycloak, etc.
    - to:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: kube-system
      ports:
        - protocol: UDP
          port: 53
        - protocol: TCP
          port: 53
    # Intra-namespace traffic between Harbor components.
    - to:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: {{ .Release.Namespace }}
    # CNPG metadata DB — the actual Postgres workload Pods (the ones
    # Harbor must reach on 5432) live in the same namespace as the
    # CNPG `Cluster` CR (default `.Release.Namespace`, overridable via
    # `postgres.cluster.namespace`), NOT in the cnpg-system operator
    # namespace. Select by the operator-emitted
    # `cnpg.io/cluster=<clusterName>` Pod label so the rule survives
    # the operator namespace being different from the data-plane
    # namespace (issue #1901).
    - to:
        - podSelector:
            matchLabels:
              cnpg.io/cluster: {{ .Values.postgres.cluster.name | default "harbor-pg" }}
      ports:
        - protocol: TCP
          port: 5432
    # Cloud-native S3 endpoint — registry blob backend per ADR-0001 §13.
    # On Hetzner Sovereigns this resolves to https://<region>.your-
    # objectstorage.com (external HTTPS); on AWS/GCP/Azure Sovereigns
    # the equivalent native endpoint. The egress rule allows any
    # external HTTPS so it doesn't need to be vendor-aware.
    {{- if .Values.objectStorage.enabled }}
    - to:
        - ipBlock:
            cidr: 0.0.0.0/0
            except:
              - 10.0.0.0/8
              - 172.16.0.0/12
              - 192.168.0.0/16
      ports:
        - protocol: TCP
          port: 443
    {{- end }}
    # Keycloak OIDC discovery (when SSO enabled).
    {{- if .Values.harborOverlay.sso.enabled }}
    - to:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: {{ .Values.harborOverlay.networkPolicy.keycloakNamespace | default "keycloak" }}
      ports:
        - protocol: TCP
          port: 8080
        - protocol: TCP
          port: 8443
    {{- end }}
    # Pull-mirror egress to public registries (when enabled).
    {{- if .Values.harborOverlay.pullMirror.enabled }}
    - to:
        - ipBlock:
            cidr: 0.0.0.0/0
            except:
              - 10.0.0.0/8
              - 172.16.0.0/12
              - 192.168.0.0/16
      ports:
        - protocol: TCP
          port: 443
    {{- end }}
{{- end }}
