---
# Wait for upgrade
- name: Confirm node upgrade
  pause:
    echo: yes
    prompt: "Ready to upgrade node ?"
  when:
    - upgrade_node_confirm

- name: Wait before upgrade node
  pause:
    seconds: "{{ upgrade_node_pause_seconds }}"
  when:
    - not upgrade_node_confirm
    - upgrade_node_pause_seconds != 0

# Node Ready: type = ready, status = True
# Node NotReady: type = ready, status = Unknown
- name: See if node is in ready state
  shell: >-
    {{ bin_dir }}/kubectl get node {{ kube_override_hostname|default(inventory_hostname) }}
    -o jsonpath='{ range .status.conditions[?(@.type == "Ready")].status }{ @ }{ end }'
  register: kubectl_node_ready
  delegate_to: "{{ groups['kube_control_plane'][0] }}"
  failed_when: false
  changed_when: false

# SchedulingDisabled: unschedulable = true
# else unschedulable key doesn't exist
- name: See if node is schedulable
  shell: >-
    {{ bin_dir }}/kubectl get node {{ kube_override_hostname|default(inventory_hostname) }}
    -o jsonpath='{ .spec.unschedulable }'
  register: kubectl_node_schedulable
  delegate_to: "{{ groups['kube_control_plane'][0] }}"
  failed_when: false
  changed_when: false

- name: Set if node needs cordoning
  set_fact:
    needs_cordoning: >-
      {% if (kubectl_node_ready.stdout == "True" and not kubectl_node_schedulable.stdout) or upgrade_node_always_cordon -%}
      true
      {%- else -%}
      false
      {%- endif %}

- name: Node draining
  block:
    - name: Cordon node
      command: "{{ bin_dir }}/kubectl cordon {{ kube_override_hostname|default(inventory_hostname) }}"
      delegate_to: "{{ groups['kube_control_plane'][0] }}"

    - name: Check kubectl version
      command: "{{ bin_dir }}/kubectl version --client --short"
      register: kubectl_version
      delegate_to: "{{ groups['kube_control_plane'][0] }}"
      run_once: yes
      changed_when: false
      when:
        - drain_nodes
        - drain_pod_selector

    - name: Ensure minimum version for drain label selector if necessary
      assert:
        that: "kubectl_version.stdout.split(' ')[-1] is version('v1.10.0', '>=')"
      when:
        - drain_nodes
        - drain_pod_selector

    - name: Drain node
      command: >-
        {{ bin_dir }}/kubectl drain
        --force
        --ignore-daemonsets
        --grace-period {{ drain_grace_period }}
        --timeout {{ drain_timeout }}
        --delete-local-data {{ kube_override_hostname|default(inventory_hostname) }}
        {% if drain_pod_selector %}--pod-selector '{{ drain_pod_selector }}'{% endif %}
      when: drain_nodes
      register: result
      until: result.rc == 0
      retries: "{{ drain_retries }}"
      delay: "{{ drain_retry_delay_seconds }}"
  rescue:
    - name: Set node back to schedulable
      command: "{{ bin_dir }}/kubectl --kubeconfig {{ kube_config_dir }}/admin.conf uncordon {{ inventory_hostname }}"
      when: upgrade_node_uncordon_after_drain_failure
    - name: Fail after rescue
      fail:
        msg: "Failed to drain node {{ inventory_hostname }}"
      when: upgrade_node_fail_if_drain_fails
  delegate_to: "{{ groups['kube_control_plane'][0] }}"
  when:
    - needs_cordoning
