# Copyright 2020 The Kubermatic Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: openvpn-client
  namespace: kube-system
spec:
  selector:
    matchLabels:
      role: openvpn-client
  updateStrategy:
    rollingUpdate:
      maxUnavailable: 1
    type: RollingUpdate
  template:
    metadata:
      labels:
        role: openvpn-client
    spec:
      containers:
      - args:
        - --config
        - /etc/openvpn/config/config
        command:
        - /usr/sbin/openvpn
        image: quay.io/kubermatic/openvpn:v2.4.8-r1
        imagePullPolicy: IfNotPresent
        livenessProbe:
          exec:
            command:
            - /bin/ping
            - -c
            - "1"
            - -w
            - "5"
            - 10.20.0.1
          initialDelaySeconds: 60
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 1
        name: openvpn-client
        readinessProbe:
          exec:
            command:
            - /bin/ping
            - -c
            - "1"
            - -w
            - "5"
            - 10.20.0.1
          failureThreshold: 3
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 1
        resources:
          limits:
            cpu: 100m
            memory: 32Mi
          requests:
            cpu: 5m
            memory: 5Mi
        securityContext:
          privileged: true
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        volumeMounts:
        - mountPath: /etc/openvpn/config
          name: openvpn-client-config
          readOnly: true
        - mountPath: /etc/openvpn/certs
          name: openvpn-client-certificates
          readOnly: true
      - command:    #TODO check function and why needed
        - bash
        - -ec
        - |
          # make sure we have two chains:
          iptables -t nat -N host_dnat || true
          iptables -t nat -N host_dnat_inactive || true
          iptables -t nat -D PREROUTING -j host_dnat || true
          iptables -t nat -D PREROUTING -j host_dnat_inactive || true

          virtualnodenet='10.254.0.0/16'

          # access node list via kubectl and generate iptables rules
          # for DNAT from it.
          while sleep 5; do
            echo 1 > /proc/sys/net/ipv4/ip_forward
            iptables -t nat -F host_dnat_inactive
            # query nodes and create DNAT rules in inactive chain
            kubectl get nodes -o json \
                | jq -r '.items[]|  (.metadata|.name+" "+.uid) + " " + (.status.addresses[]|select(.type=="InternalIP")|.address)' \
                | while read name uid ip; do
                    left=$( echo $virtualnodenet | cut -d. -f1-2 )
                    right=$( echo $ip | cut -d. -f3-4 )
                    iptables -t nat -A host_dnat_inactive -d $left.$right -j DNAT --to $ip
                done
                # swap the chains (inactive / active):
                iptables -t nat -I PREROUTING -j host_dnat_inactive
                iptables -t nat -D PREROUTING -j host_dnat || true
                iptables -t nat -E host_dnat host_dnat_old
                iptables -t nat -E host_dnat_inactive host_dnat
                iptables -t nat -E host_dnat_old host_dnat_inactive
          done
          echo "Terminating."
        image: quay.io/kubermatic/openvpn:v2.4.8-r1
        imagePullPolicy: IfNotPresent
        name: dnat-controller
        resources:
          limits:
            cpu: 100m
            memory: 50Mi
          requests:
            cpu: 25m
            memory: 25Mi
        securityContext:
          privileged: true
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      hostNetwork: true
      restartPolicy: Always
      securityContext: {}
      serviceAccountName: vpn-client
      terminationGracePeriodSeconds: 5
      volumes:
      - name: openvpn-client-certificates
        secret:
          defaultMode: 256
          secretName: openvpn-client-certificates
      - configMap:
          defaultMode: 420
          name: openvpn-client-config
        name: openvpn-client-config
