apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress
  namespace: {{ .Release.Namespace }}
  annotations:
    acme.cert-manager.io/http01-edit-in-place: "true"
    cert-manager.io/cluster-issuer: {{ .Values.certificateIssuer}}
    {{ if .Values.ui.enabled }}
    nginx.org/rewrites: "serviceName=headscale rewrite=/;serviceName=headscale-ui rewrite=/"
    {{ end }}
spec:
  ingressClassName: {{ .Values.ingressClassName }}
  tls:
  - hosts:
    - {{ .Values.domain }}
    secretName: cert-{{ .Values.domain }}
  rules:
  - host: {{ .Values.domain }}
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: headscale
            port:
              name: http
      {{ if .Values.ui.enabled }}
      - path: /web
        pathType: Prefix
        backend:
          service:
            name: headscale-ui
            port:
              name: http
      {{ end }}
---
apiVersion: v1
kind: Service
metadata:
  name: headscale
  namespace: {{ .Release.Namespace }}
  annotations:
    metallb.universe.tf/address-pool: {{ .Values.ipAddressPool }}
spec:
  type: LoadBalancer
  selector:
    app: headscale
  ports:
  - name: http
    port: 80
    targetPort: http
    protocol: TCP
{{ if .Values.ui.enabled }}
---
apiVersion: v1
kind: Service
metadata:
  name: headscale-ui
  namespace: {{ .Release.Namespace }}
  # annotations:
  #   metallb.universe.tf/address-pool: {{ .Values.ipAddressPool }}
spec:
  type: ClusterIP
  selector:
    app: headscale
  ports:
  - name: http
    port: 80
    targetPort: http-ui
    protocol: TCP
{{ end }}
---
apiVersion: v1
kind: Service
metadata:
  name: headscale-api
  namespace: {{ .Release.Namespace }}
spec:
  type: ClusterIP
  selector:
    app: headscale
  ports:
  - name: http
    port: 80
    targetPort: http-api
    protocol: TCP
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: data
  namespace: {{ .Release.Namespace }}
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: {{ .Values.storage.size }}
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: acls
  namespace: {{ .Release.Namespace }}
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi # TODO(gio): configurable
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: headscale
  namespace: {{ .Release.Namespace }}
spec:
  selector:
    matchLabels:
      app: headscale
  serviceName: headscale
  replicas: 1
  template:
    metadata:
      labels:
        app: headscale
    spec:
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: data
      - name: acls
        persistentVolumeClaim:
          claimName: acls
      - name: config
        configMap:
          name: config
      - name: api-socket
        emptyDir: {}
      containers:
      - name: headscale
        image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
        imagePullPolicy: {{ .Values.image.pullPolicy }}
        ports:
        - name: http
          containerPort: 8080
          protocol: TCP
        - name: grpc
          containerPort: 50443
          protocol: TCP
        command:
        - headscale
        - --config=/headscale/config/config.yaml
        - serve
        volumeMounts:
        - name: data
          mountPath: /headscale/data
          readOnly: false
        - name: config
          mountPath: /headscale/config
          readOnly: true
        - name: acls
          mountPath: /headscale/acls
          readOnly: true
        - mountPath: /headscale-api
          name: api-socket
        livenessProbe:
          exec:
            command:
              - cat
              - /headscale/acls/config.hujson-reload
            initialDelaySeconds: 60
            periodSeconds: 5
      - name: headscale-api
        image: {{ .Values.api.image.repository }}:{{ .Values.api.image.tag }}
        imagePullPolicy: {{ .Values.api.image.pullPolicy }}
        ports:
        - name: http-api
          containerPort: {{ .Values.api.port }}
          protocol: TCP
        command:
        - headscale-api
        - --port={{ .Values.api.port }}
        - --config=/headscale/config/config.yaml
        - --ip-subnet={{ .Values.api.ipSubnet }}
        - --acls=/headscale/acls/config.hujson
        - --self={{ .Values.api.self }}
        - --fetch-users-addr={{ .Values.api.fetchUsersAddr }}
        livenessProbe:
          exec:
            command:
              - cat
              - /headscale/acls/config.hujson-reload
            initialDelaySeconds: 60
            periodSeconds: 5
        volumeMounts:
        - name: data
          mountPath: /headscale/data
          readOnly: false
        - name: config
          mountPath: /headscale/config
          readOnly: true
        - name: acls
          mountPath: /headscale/acls
          readOnly: false
        - mountPath: /headscale-api
          name: api-socket
      {{ if .Values.ui.enabled }}
      - name: headscale-ui # TODO(gio): separate deployment
        image: {{ .Values.ui.image.repository }}:{{ .Values.ui.image.tag }}
        imagePullPolicy: {{ .Values.ui.image.pullPolicy }}
        ports:
        - name: http-ui
          containerPort: 80
          protocol: TCP
      {{ end }}
