---
- name: Kubectl | Fail if playbook is executed on K8s master
  fail:
    msg: "The k8s_client_certs.yml playbook is not meant to run on K8s master"
  when: master

- name: K8s Client Certificates | Include vars
  include_vars: "{{ ansible_distribution | lower }}.yml"

- name: K8s Client Certificates | Include global vars
  include_vars: "{{ ansible_tmp_dir }}/generated_global_vars.yml"

- name: K8s Client Certificates | Assume client certs are not missing
  set_fact:
    k8s_client_certs_missing: false

- name: K8s Client Certificates | Verify if all the client certs are present
  block:
    - name: K8s Client Certificates | Get the client cert file stat
      stat:
        path: "{{ k8s_client_certs.directory }}/node.pem"
      register: client_cert

    - name: K8s Client Certificates | Get the client cert key file stat
      stat:
        path: "{{ k8s_client_certs.directory }}/node-key.pem"
      register: client_cert_key

    - name: K8s Client Certificates | Set the "k8s_client_certs_missing" flag if either cert or cert key is missing
      set_fact:
        k8s_client_certs_missing: true
      when: not client_cert.stat.exists or not client_cert_key.stat.exists

- name: K8s Client Certificates | Generate client certificates
  block:
    - name: K8s Client Certificates | Create k8s certs directory
      file:
        path: "{{ k8s_client_certs.directory }}"
        state: directory
        mode: "u=rwx,g=rx,o=rx"

    - name: K8s Client Certificates | Copy the CA cert and key
      copy:
        src: "{{ansible_tmp_dir}}/k8s_{{item}}"
        dest: "{{ k8s_client_certs.directory }}/{{item}}"
      with_items:
        - ca.pem
        - ca-key.pem

    - name: K8s Client Certificates | Remove the tmp certs directory if exists
      file:
        path: "{{ k8s_client_certs.tmp_generate_path }}"
        state: absent

    - name: K8s Client Certificates | Create the tmp certs directory
      file:
        path: "{{ k8s_client_certs.tmp_generate_path }}"
        state: directory
        mode: "u=rwx,g=rx,o=rx"

    - name: K8s Client Certificates | Create the make-certs bash script
      lineinfile:
        path: "{{ k8s_client_certs.tmp_generate_path }}/make-certs"
        mode: "u=rwx,g=rx,o=rx"
        create: yes
        line: |
          #!/bin/bash -

          set -o errexit
          set -o nounset
          set -o pipefail

          cert_group=kube-cert
          cert_dir="{{ k8s_client_certs.directory }}"

          pem_ca=$cert_dir/ca.pem
          pem_ca_key=$cert_dir/ca-key.pem

          pem_node=$cert_dir/node.pem
          pem_node_key=$cert_dir/node-key.pem
          pem_node_csr=$cert_dir/node-csr.pem

          # Make sure cert group exists
          [ $(getent group $cert_group) ] || groupadd -r $cert_group

          # Make sure perms are right
          chgrp $cert_group $pem_ca $pem_ca_key
          chmod 600 $pem_ca_key
          chmod 660 $pem_ca

          # Generate TLS artifacts
          openssl genrsa -out $pem_node_key 2048
          openssl req -new -key $pem_node_key -out $pem_node_csr -subj "/CN={{ ansible_hostname }}" -config openssl.cnf
          openssl x509 -req -in $pem_node_csr -CA $pem_ca -CAkey $pem_ca_key -CAcreateserial -out $pem_node -days 365 -extensions v3_req -extfile openssl.cnf

          # Make server certs accessible to apiserver.
          chgrp $cert_group $pem_node $pem_node_key
          chmod 600 $pem_node_key
          chmod 660 $pem_node $pem_ca

    - name: K8s Client Certificates | Create the openssl conf for certs generation
      lineinfile:
        path: "{{ k8s_client_certs.tmp_generate_path }}/openssl.cnf"
        create: yes
        line: |
          [req]
          req_extensions = v3_req
          distinguished_name = req_distinguished_name
          [req_distinguished_name]
          [ v3_req ]
          basicConstraints = CA:FALSE
          keyUsage = nonRepudiation, digitalSignature, keyEncipherment
          subjectAltName = @alt_names
          [alt_names]
          IP.1 = {{ ansible_default_ipv4.address }}

    - name: K8s Client Certificates | Generate k8s client certificates for the current machine
      shell: ./make-certs
      args:
        executable: /bin/bash
        chdir: "{{ k8s_client_certs.tmp_generate_path }}"

    - name: K8s Client Certificates | Remove tmp dir for certs generation
      file:
        path: "{{ k8s_client_certs.tmp_generate_path }}"
        state: absent
  when: k8s_client_certs_missing or certs_generated
