---
- name: Install pexpect python module for the expect task
  pip: name=pexpect state=latest

- name: Ensure openvpn data volume exists
  docker_volume: name={{ openvpn_data_volume }} state=present

- name: Check for openvpn config
  command: docker run -v {{ openvpn_data_volume }}:/etc/openvpn --rm -it {{ openvpn_docker_image }} ls /etc/openvpn/openvpn.conf
  ignore_errors: yes
  check_mode: no
  changed_when: False
  register: openvpn_config_check

- name: Ensure openvpn config is generated
  docker_container:
    name: "tmp-openvpn-genconfig"
    image: "{{ openvpn_docker_image }}"
    detach: no
    cleanup: yes
    volumes:
      - "{{ openvpn_data_volume }}:/etc/openvpn"
    entrypoint: "ovpn_genconfig -u udp://{{ openvpn_public_domain }}"
  when: openvpn_config_check.rc == 1

- name: Check for pki infrastructure
  command: docker run -v {{ openvpn_data_volume }}:/etc/openvpn --rm -it {{ openvpn_docker_image }} ls /etc/openvpn/pki
  ignore_errors: yes
  check_mode: no
  changed_when: False
  register: openvpn_pki_check

- name: "Generate PKI"
  expect:
    command: docker run -v {{ openvpn_data_volume }}:/etc/openvpn --rm -it {{ openvpn_docker_image }} ovpn_initpki
    timeout: 300 # 5 minutes (Generating DH Params takes time)
    responses:
      "Passphrase": "{{ openvpn_pki_pass  }}"
      "pass phrase": "{{ openvpn_pki_pass  }}"
      "Common Name": "{{ openvpn_public_domain  }}"
  when: openvpn_pki_check.rc == 1

- name: Ensure openvpn TCP container is started
  docker_container:
    name: "ovpn-{{ item.proto }}"
    image: "{{ openvpn_docker_image }}"
    restart_policy: always
    capabilities:
      - NET_ADMIN
    networks_cli_compatible: yes
    networks:
      - name: "{{ traefik_docker_network }}"
    dns_servers:
      # DNS replies must come back from the docker gateway or
      # they are rejected as spoofing attempts.
      - "{{ ansible_docker0.ipv4.address }}"
    volumes:
      - "{{ openvpn_data_volume }}:/etc/openvpn"
    command: ovpn_run --proto {{ item.proto }}
    labels:
      traefik.tcp.routers.openvpn.rule: "HostSNI(`*`)"
      traefik.tcp.routers.openvpn.entrypoints: "websecure"
      traefik.tcp.routers.openvpn.tls: "false"
      traefik.tcp.routers.openvpn.service: "openvpn"
      
      traefik.tcp.services.openvpn.loadBalancer.server.port: "1194"
  with_items:
    - { port: 443, proto: tcp }
  register: "docker_vpn_container_status"

- name: Ensure openvpn UDP container is started
  docker_container:
    name: "ovpn-{{ item.proto }}"
    image: "{{ openvpn_docker_image }}"
    restart_policy: always
    capabilities:
      - NET_ADMIN
    # CLI compatibility is default in Ansible 2.12 (not yet released) and below rule suppresses warning
    networks_cli_compatible: yes
    networks:
      - name: "{{ traefik_docker_network }}"
    dns_servers:
      # DNS replies must come back from the docker gateway or
      # they are rejected as spoofing attempts.
      - "{{ ansible_docker0.ipv4.address }}"
    volumes:
      - "{{ openvpn_data_volume }}:/etc/openvpn"
    command: ovpn_run --proto {{ item.proto }}
    labels:
      traefik.udp.routers.openvpn.entrypoints: "openvpn"
      traefik.udp.routers.openvpn.service: "openvpn"
      traefik.udp.services.openvpn.loadBalancer.server.port: "1194"
  with_items:
    - { port: 1194, proto: udp }

- name: Get current client list
  command: docker run -v {{ openvpn_data_volume }}:/etc/openvpn --rm {{ openvpn_docker_image }} ovpn_listclients
  check_mode: no
  register: openvpn_client_list
  changed_when: false

- name: Ensure client keys are generated
  expect:
    command: "docker run -v {{ openvpn_data_volume }}:/etc/openvpn --rm -it {{ openvpn_docker_image }} easyrsa build-client-full {{ item }} nopass"
    responses:
      "pass phrase": "{{ openvpn_pki_pass }}"
  when: "openvpn_client_list.stdout.find(item) == -1"
  with_items: "{{ openvpn_clients }}"

- name: Save generated keys on "{{ ansible_hostname }}"
  shell: docker run -v {{ openvpn_data_volume }}:/etc/openvpn --rm {{ openvpn_docker_image }} ovpn_getclient {{ item }} > {{ openvpn_key_dir }}/{{ item }}.ovpn
  args:
    creates: "{{ openvpn_key_dir }}/{{ item }}.ovpn"
  with_items: "{{ openvpn_clients }}"
  become: yes
  become_user: "{{ user }}"
  when: "openvpn_key_dir is defined"
