- name: Create user k8s service account
  environment:
    PATH: "{{ k8s_venv }}/bin:{{ ansible_env.PATH }}"
  vars:
    ansible_python_interpreter: "{{ k8s_venv }}/bin/python"
  kubernetes.core.k8s:
    state: present
    kubeconfig: "{{ k8s_kubeconfig }}"
    wait: true
    definition:
      apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: "{{ microk8s_iac_user }}"
        namespace: default
  tags:
    - k8s::iac

- name: Create secret token
  environment:
    PATH: "{{ k8s_venv }}/bin:{{ ansible_env.PATH }}"
  vars:
    ansible_python_interpreter: "{{ k8s_venv }}/bin/python"
  kubernetes.core.k8s:
    state: present
    kubeconfig: "{{ k8s_kubeconfig }}"
    wait: true
    definition:
      apiVersion: v1
      kind: Secret
      metadata:
        name: "{{ microk8s_iac_user }}-token"
        namespace: default
        annotations:
          kubernetes.io/service-account.name: "{{ microk8s_iac_user }}"
      type: kubernetes.io/service-account-token
  tags:
    - k8s::iac

- name: Enabled IaC admin access to k8s
  environment:
    PATH: "{{ k8s_venv }}/bin:{{ ansible_env.PATH }}"
  vars:
    ansible_python_interpreter: "{{ k8s_venv }}/bin/python"
  kubernetes.core.k8s:
    state: present
    kubeconfig: "{{ k8s_kubeconfig }}"
    wait: true
    definition:
      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRoleBinding
      metadata:
        name: admin-role-binding
      roleRef:
        apiGroup: rbac.authorization.k8s.io
        kind: ClusterRole
        name: cluster-admin
      subjects:
        - kind: ServiceAccount
          namespace: default
          name: "{{ microk8s_iac_user }}"
  tags:
    - k8s::iac

- name: Get the secret name
  ansible.builtin.shell: |
    set -o pipefail
    microk8s.kubectl -n default get secret | grep {{ microk8s_iac_user }} | awk '{ print $1 }'
  args:
    executable: /bin/bash
  register: secret_name
  tags:
    - k8s::iac
  changed_when: false

- name: Describe the secret and extract the token
  ansible.builtin.shell: |
    set -o pipefail
    microk8s.kubectl -n default describe secret {{ secret_name.stdout }} | grep token: | awk '{ print $2 }'
  args:
    executable: /bin/bash
  register: token
  tags:
    - k8s::iac
  changed_when: false

- name: Read system kubeconfig
  become: true
  ansible.builtin.command: "microk8s config"
  register: kubeconfig
  tags:
    - k8s::iac
  changed_when: false

- name: Set fact kubeconfig
  ansible.builtin.set_fact:
    kubeconfig_yaml: "{{ kubeconfig.stdout | from_yaml }}"
  tags:
    - k8s::iac

- name: Render kubeconfig
  when: kubeconfig.stdout != ""
  block:
    - name: Patch kubeconfig with user token
      ansible.builtin.set_fact:
        patched_kubeconfig_yaml: "{{ kubeconfig_yaml | combine(new_kubeconfig, recursive=True) }}"
      vars:
        new_kubeconfig:
          contexts:
            - context:
                cluster: microk8s-cluster
                user: "{{ microk8s_iac_user }}"
              name: microk8s
          users:
            - name: "{{ microk8s_iac_user }}"
              user:
                token: "{{ token.stdout }}"
      tags:
        - k8s::iac

    - name: Check if a config already exists and its SHA1
      become: true
      ansible.builtin.stat:
        path: "{{ k8s_kubeconfig }}"
      register: kubeconfig_exists
      tags:
        - k8s::iac

    - name: Get new config SHA1
      ansible.builtin.set_fact:
        patched_kubeconfig_sha1: "{{ patched_kubeconfig_yaml | to_nice_yaml | sha1 }}"
      tags:
        - k8s::iac

    - name: Write kubeconfig
      become: true
      ansible.builtin.copy:
        content: "{{ patched_kubeconfig_yaml | to_nice_yaml }}"
        dest: "{{ k8s_kubeconfig }}"
        owner: "{{ microk8s_iac_user }}"
        mode: "0600"
      when:
        - not kubeconfig_exists.stat.exists or patched_kubeconfig_sha1 != kubeconfig_exists.stat.checksum
      tags:
        - k8s::iac
