---
- name: Set kubeadm_discovery_address
  set_fact:
    # noqa: jinja[spacing]
    kubeadm_discovery_address: >-
      {%- if "127.0.0.1" in kube_apiserver_endpoint or "localhost" in kube_apiserver_endpoint -%}
      {{ first_kube_control_plane_address | ansible.utils.ipwrap }}:{{ kube_apiserver_port }}
      {%- else -%}
      {{ kube_apiserver_endpoint | regex_replace('https://', '') }}
      {%- endif %}
  tags:
    - facts

- name: Upload certificates so they are fresh and not expired
  command: >-
    {{ bin_dir }}/kubeadm init phase
    --config {{ kube_config_dir }}/kubeadm-config.yaml
    upload-certs
    --upload-certs
  register: kubeadm_upload_cert
  when:
    - inventory_hostname == first_kube_control_plane
    - not kube_external_ca_mode

- name: Parse certificate key if not set
  set_fact:
    kubeadm_certificate_key: "{{ hostvars[first_kube_control_plane]['kubeadm_upload_cert'].stdout_lines[-1] | trim }}"
  run_once: true
  when:
    - hostvars[first_kube_control_plane]['kubeadm_upload_cert'] is defined
    - hostvars[first_kube_control_plane]['kubeadm_upload_cert'] is not skipped

- name: Create kubeadm ControlPlane config
  template:
    src: "kubeadm-controlplane.yaml.j2"
    dest: "{{ kube_config_dir }}/kubeadm-controlplane.yaml"
    mode: "0640"
    backup: true
    validate: "{{ kubeadm_config_validate_enabled | ternary(bin_dir + '/kubeadm config validate --config %s', omit) }}"
  when:
    - inventory_hostname != first_kube_control_plane
    - not kubeadm_already_run.stat.exists

- name: Wait for k8s apiserver
  wait_for:
    host: "{{ kubeadm_discovery_address | regex_replace('\\]?:\\d+$', '') | regex_replace('^\\[', '') }}"
    port: "{{ kubeadm_discovery_address.split(':')[-1] }}"
    timeout: 180


- name: Check already run
  debug:
    msg: "{{ kubeadm_already_run.stat.exists }}"

- name: Reset cert directory
  shell: >-
    if [ -f /etc/kubernetes/manifests/kube-apiserver.yaml ]; then
    {{ bin_dir }}/kubeadm reset -f --cert-dir {{ kube_cert_dir }};
    fi
  environment:
    PATH: "{{ bin_dir }}:{{ ansible_env.PATH }}"
  when:
    - inventory_hostname != first_kube_control_plane
    - kubeadm_already_run is not defined or not kubeadm_already_run.stat.exists
    - not kube_external_ca_mode

- name: Get kubeconfig for join discovery process
  command: "{{ kubectl }} -n kube-public get cm cluster-info -o jsonpath='{.data.kubeconfig}'"
  register: kubeconfig_file_discovery
  run_once: true
  delegate_to: "{{ groups['kube_control_plane'] | first }}"
  when:
    - kubeadm_use_file_discovery
    - kubeadm_already_run is not defined or not kubeadm_already_run.stat.exists

- name: Copy discovery kubeconfig
  copy:
    dest: "{{ kube_config_dir }}/cluster-info-discovery-kubeconfig.yaml"
    content: "{{ kubeconfig_file_discovery.stdout }}"
    owner: "root"
    mode: "0644"
  when:
    - inventory_hostname != first_kube_control_plane
    - kubeadm_use_file_discovery
    - kubeadm_already_run is not defined or not kubeadm_already_run.stat.exists

- name: Joining control plane node to the cluster.
  command: >-
    {{ bin_dir }}/kubeadm join
    --config {{ kube_config_dir }}/kubeadm-controlplane.yaml
    --ignore-preflight-errors={{ kubeadm_ignore_preflight_errors | join(',') }}
    --skip-phases={{ kubeadm_join_phases_skip | join(',') }}
  environment:
    PATH: "{{ bin_dir }}:{{ ansible_env.PATH }}"
  register: kubeadm_join_control_plane
  retries: 3
  throttle: 1
  until: kubeadm_join_control_plane is succeeded
  when:
    - inventory_hostname != first_kube_control_plane
    - kubeadm_already_run is not defined or not kubeadm_already_run.stat.exists

- name: Wait for new control plane nodes to be Ready
  when: kubeadm_already_run.stat.exists
  run_once: true
  command: >
    {{ kubectl }} get nodes --selector node-role.kubernetes.io/control-plane
    -o jsonpath-as-json="{.items[*].status.conditions[?(@.type == 'Ready')]}"
  register: control_plane_node_ready_conditions
  retries: "{{ control_plane_node_become_ready_tries }}"
  delay: 5
  delegate_to: "{{ groups['kube_control_plane'][0] }}"
  until: >
    control_plane_node_ready_conditions.stdout
    | from_json | selectattr('status', '==', 'True')
    | length == (groups['kube_control_plane'] | length)
