{{- $HTTPS := .Values.proxy.https.enabled -}}
{{- $autoHTTPS := and $HTTPS (and (eq .Values.proxy.https.type "letsencrypt") .Values.proxy.https.hosts) -}}
{{- if and $autoHTTPS .Values.proxy.traefik.networkPolicy.enabled -}}
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: {{ include "jupyterhub.autohttps.fullname" . }}
  labels:
    {{- include "jupyterhub.labels" . | nindent 4 }}
spec:
  podSelector:
    matchLabels:
      {{- include "jupyterhub.matchLabels" . | nindent 6 }}
  policyTypes:
    - Ingress
    - Egress

  # IMPORTANT:
  # NetworkPolicy's ingress "from" and egress "to" rule specifications require
  # great attention to detail. A quick summary is:
  #
  # 1. You can provide "from"/"to" rules that provide access either ports or a
  #    subset of ports.
  # 2. You can for each "from"/"to" rule provide any number of
  #    "sources"/"destinations" of four different kinds.
  #    - podSelector                        - targets pods with a certain label in the same namespace as the NetworkPolicy
  #    - namespaceSelector                  - targets all pods running in namespaces with a certain label
  #    - namespaceSelector and podSelector  - targets pods with a certain label running in namespaces with a certain label
  #    - ipBlock                            - targets network traffic from/to a set of IP address ranges
  #
  # Read more at: https://kubernetes.io/docs/concepts/services-networking/network-policies/#behavior-of-to-and-from-selectors
  #
  ingress:
    {{- with .Values.proxy.traefik.networkPolicy.allowedIngressPorts }}
    # allow incoming traffic to these ports independent of source
    - ports:
      {{- range $port := . }}
      - port: {{ $port }}
      {{- end }}
    {{- end }}

    # allowed pods (hub.jupyter.org/network-access-proxy-http) --> proxy (http/https port)
    - ports:
        - port: http
        - port: https
      from:
        # source 1 - labeled pods
        - podSelector:
            matchLabels:
              hub.jupyter.org/network-access-proxy-http: "true"
        {{- if eq .Values.proxy.traefik.networkPolicy.interNamespaceAccessLabels "accept" }}
          namespaceSelector:
            matchLabels: {}   # without this, the podSelector would only consider pods in the local namespace
        # source 2 - pods in labeled namespaces
        - namespaceSelector:
            matchLabels:
              hub.jupyter.org/network-access-proxy-http: "true"
        {{- end }}

    {{- with .Values.proxy.traefik.networkPolicy.ingress}}
    # depends, but default is nothing --> proxy
    {{- . | toYaml | nindent 4 }}
    {{- end }}

  egress:
    # autohttps --> proxy (http port)
    - to:
        - podSelector:
            matchLabels:
              {{- $_ := merge (dict "componentLabel" "proxy") . }}
              {{- include "jupyterhub.matchLabels" $_ | nindent 14 }}
      ports:
        - port: 8000

    {{- with (include "jupyterhub.networkPolicy.renderEgressRules" (list . .Values.proxy.traefik.networkPolicy)) }}
    {{- . | nindent 4 }}
    {{- end }}
{{- end }}
