---
- name: Reset | stop services
  service:
    name: "{{ item }}"
    state: stopped
  with_items:
    - kubelet.service
    - cri-dockerd.service
    - cri-dockerd.socket
  failed_when: false
  tags:
    - services

- name: Reset | remove services
  file:
    path: "/etc/systemd/system/{{ item }}"
    state: absent
  with_items:
    - kubelet.service
    - cri-dockerd.service
    - cri-dockerd.socket
    - calico-node.service
    - containerd.service.d/http-proxy.conf
    - crio.service.d/http-proxy.conf
    - k8s-certs-renew.service
    - k8s-certs-renew.timer
  register: services_removed
  tags:
    - services
    - containerd
    - crio

- name: Reset | Remove Docker
  include_role:
    name: container-engine/docker
    tasks_from: reset
  when: container_manager == 'docker'
  tags:
    - docker

- name: Reset | systemctl daemon-reload  # noqa no-handler
  systemd:
    daemon_reload: true
  when: services_removed.changed

- name: Reset | check if crictl is present
  stat:
    path: "{{ bin_dir }}/crictl"
    get_attributes: no
    get_checksum: no
    get_mime: no
  register: crictl

- name: Reset | stop all cri containers
  shell: "set -o pipefail && {{ bin_dir }}/crictl ps -q | xargs -r {{ bin_dir }}/crictl -t 60s stop -t {{ cri_stop_containers_grace_period }}"
  args:
    executable: /bin/bash
  register: remove_all_cri_containers
  retries: 5
  until: remove_all_cri_containers.rc == 0
  delay: 5
  tags:
    - crio
    - containerd
  when:
    - crictl.stat.exists
    - container_manager in ["crio", "containerd"]
    - ansible_facts.services['containerd.service'] is defined or ansible_facts.services['cri-o.service'] is defined
  ignore_errors: true  # noqa ignore-errors

- name: Reset | force remove all cri containers
  command: "{{ bin_dir }}/crictl rm -a -f"
  register: remove_all_cri_containers
  retries: 5
  until: remove_all_cri_containers.rc == 0
  delay: 5
  tags:
    - crio
    - containerd
  when:
    - crictl.stat.exists
    - container_manager in ["crio", "containerd"]
    - deploy_container_engine
    - ansible_facts.services['containerd.service'] is defined or ansible_facts.services['cri-o.service'] is defined
  ignore_errors: true  # noqa ignore-errors

- name: Reset | stop and disable crio service
  service:
    name: crio
    state: stopped
    enabled: false
  failed_when: false
  tags: [ crio ]
  when: container_manager == "crio"

- name: Reset | forcefully wipe CRI-O's container and image storage
  command: "crio wipe -f"
  failed_when: false
  tags: [ crio ]
  when: container_manager == "crio"

- name: Reset | stop all cri pods
  shell: "set -o pipefail && {{ bin_dir }}/crictl pods -q | xargs -r {{ bin_dir }}/crictl -t 60s stopp"
  args:
    executable: /bin/bash
  register: remove_all_cri_containers
  retries: 5
  until: remove_all_cri_containers.rc == 0
  delay: 5
  tags: [ containerd ]
  when:
    - crictl.stat.exists
    - container_manager == "containerd"
    - ansible_facts.services['containerd.service'] is defined or ansible_facts.services['cri-o.service'] is defined
  ignore_errors: true  # noqa ignore-errors

- name: Reset | force remove all cri pods
  block:
    - name: Reset | force remove all cri pods
      command: "{{ bin_dir }}/crictl rmp -a -f"
      register: remove_all_cri_containers
      retries: 5
      until: remove_all_cri_containers.rc == 0
      delay: 5
      tags: [ containerd ]
      when:
        - crictl.stat.exists
        - container_manager == "containerd"
        - ansible_facts.services['containerd.service'] is defined or ansible_facts.services['cri-o.service'] is defined

  rescue:
    - name: Reset | force remove all cri pods (rescue)
      shell: "ip netns list | cut -d' ' -f 1 | xargs -n1 ip netns delete && {{ bin_dir }}/crictl rmp -a -f"
      ignore_errors: true  # noqa ignore-errors
      changed_when: true

- name: Reset | stop etcd services
  service:
    name: "{{ item }}"
    state: stopped
  with_items:
    - etcd
    - etcd-events
  failed_when: false
  tags:
    - services

- name: Reset | remove etcd services
  file:
    path: "/etc/systemd/system/{{ item }}.service"
    state: absent
  with_items:
    - etcd
    - etcd-events
  register: services_removed
  tags:
    - services

- name: Reset | remove containerd
  when: container_manager == 'containerd'
  block:
    - name: Reset | stop containerd service
      service:
        name: containerd
        state: stopped
      failed_when: false
      tags:
        - services

    - name: Reset | remove containerd service
      file:
        path: /etc/systemd/system/containerd.service
        state: absent
      register: services_removed
      tags:
        - services

- name: Reset | gather mounted kubelet dirs
  shell: set -o pipefail && mount | grep /var/lib/kubelet/ | awk '{print $3}' | tac
  args:
    executable: /bin/bash
  check_mode: no
  register: mounted_dirs
  failed_when: false
  changed_when: false
  tags:
    - mounts

- name: Reset | unmount kubelet dirs
  command: umount -f {{ item }}
  with_items: "{{ mounted_dirs.stdout_lines }}"
  register: umount_dir
  when: mounted_dirs
  retries: 4
  until: umount_dir.rc == 0
  delay: 5
  tags:
    - mounts

- name: Flush iptables
  iptables:
    table: "{{ item }}"
    flush: yes
  with_items:
    - filter
    - nat
    - mangle
    - raw
  when: flush_iptables | bool
  tags:
    - iptables

- name: Flush ip6tables
  iptables:
    table: "{{ item }}"
    flush: yes
    ip_version: ipv6
  with_items:
    - filter
    - nat
    - mangle
    - raw
  when: flush_iptables | bool and enable_dual_stack_networks
  tags:
    - ip6tables

- name: Clear IPVS virtual server table
  command: "ipvsadm -C"
  ignore_errors: true  # noqa ignore-errors
  when:
    - kube_proxy_mode == 'ipvs' and inventory_hostname in groups['k8s_cluster']

- name: Reset | check kube-ipvs0 network device
  stat:
    path: /sys/class/net/kube-ipvs0
    get_attributes: no
    get_checksum: no
    get_mime: no
  register: kube_ipvs0

- name: Reset | Remove kube-ipvs0
  command: "ip link del kube-ipvs0"
  when:
    - kube_proxy_mode == 'ipvs'
    - kube_ipvs0.stat.exists

- name: Reset | check nodelocaldns network device
  stat:
    path: /sys/class/net/nodelocaldns
    get_attributes: no
    get_checksum: no
    get_mime: no
  register: nodelocaldns_device

- name: Reset | Remove nodelocaldns
  command: "ip link del nodelocaldns"
  when:
    - enable_nodelocaldns | default(false) | bool
    - nodelocaldns_device.stat.exists

- name: Reset | Check whether /var/lib/kubelet directory exists
  stat:
    path: /var/lib/kubelet
    get_attributes: no
    get_checksum: no
    get_mime: no
  register: var_lib_kubelet_directory

- name: Reset | Find files/dirs with immutable flag in /var/lib/kubelet
  command: lsattr -laR /var/lib/kubelet
  become: true
  register: var_lib_kubelet_files_dirs_w_attrs
  changed_when: false
  no_log: true
  when: var_lib_kubelet_directory.stat.exists

- name: Reset | Remove immutable flag from files/dirs in /var/lib/kubelet
  file:
    path: "{{ filedir_path }}"
    state: touch
    attributes: "-i"
    mode: 0644
  loop: "{{ var_lib_kubelet_files_dirs_w_attrs.stdout_lines | select('search', 'Immutable') | list }}"
  loop_control:
    loop_var: file_dir_line
    label: "{{ filedir_path }}"
  vars:
    filedir_path: "{{ file_dir_line.split(' ')[0] }}"
  when: var_lib_kubelet_directory.stat.exists

- name: Reset | delete some files and directories
  file:
    path: "{{ item }}"
    state: absent
  with_items:
    - "{{ kube_config_dir }}"
    - /var/lib/kubelet
    - "{{ containerd_storage_dir }}"
    - "{{ ansible_env.HOME | default('/root') }}/.kube"
    - "{{ ansible_env.HOME | default('/root') }}/.helm"
    - "{{ ansible_env.HOME | default('/root') }}/.config/helm"
    - "{{ ansible_env.HOME | default('/root') }}/.cache/helm"
    - "{{ ansible_env.HOME | default('/root') }}/.local/share/helm"
    - "{{ etcd_data_dir }}"
    - "{{ etcd_events_data_dir }}"
    - "{{ etcd_config_dir }}"
    - /var/log/calico
    - /var/log/openvswitch
    - /var/log/ovn
    - /var/log/kube-ovn
    - /etc/cni
    - /etc/nerdctl
    - "{{ nginx_config_dir }}"
    - /etc/dnsmasq.d
    - /etc/dnsmasq.conf
    - /etc/dnsmasq.d-available
    - /etc/systemd/resolved.conf.d/kubespray.conf
    - /etc/etcd.env
    - /etc/calico
    - /etc/NetworkManager/conf.d/calico.conf
    - /etc/NetworkManager/conf.d/k8s.conf
    - /etc/weave.env
    - /opt/cni
    - /etc/dhcp/dhclient.d/zdnsupdate.sh
    - /etc/dhcp/dhclient-exit-hooks.d/zdnsupdate
    - /run/flannel
    - /etc/flannel
    - /run/kubernetes
    - /usr/local/share/ca-certificates/etcd-ca.crt
    - /usr/local/share/ca-certificates/kube-ca.crt
    - /etc/ssl/certs/etcd-ca.pem
    - /etc/ssl/certs/kube-ca.pem
    - /etc/pki/ca-trust/source/anchors/etcd-ca.crt
    - /etc/pki/ca-trust/source/anchors/kube-ca.crt
    - /var/log/pods/
    - "{{ bin_dir }}/kubelet"
    - "{{ bin_dir }}/cri-dockerd"
    - "{{ bin_dir }}/etcd-scripts"
    - "{{ bin_dir }}/etcd"
    - "{{ bin_dir }}/etcd-events"
    - "{{ bin_dir }}/etcdctl"
    - "{{ bin_dir }}/etcdctl.sh"
    - "{{ bin_dir }}/kubernetes-scripts"
    - "{{ bin_dir }}/kubectl"
    - "{{ bin_dir }}/kubeadm"
    - "{{ bin_dir }}/helm"
    - "{{ bin_dir }}/calicoctl"
    - "{{ bin_dir }}/calicoctl.sh"
    - "{{ bin_dir }}/calico-upgrade"
    - "{{ bin_dir }}/weave"
    - "{{ bin_dir }}/crictl"
    - "{{ bin_dir }}/nerdctl"
    - "{{ bin_dir }}/netctl"
    - "{{ bin_dir }}/k8s-certs-renew.sh"
    - /var/lib/cni
    - /etc/openvswitch
    - /run/openvswitch
    - /var/lib/kube-router
    - /var/lib/calico
    - /etc/cilium
    - /run/calico
    - /etc/bash_completion.d/kubectl.sh
    - /etc/bash_completion.d/crictl
    - /etc/bash_completion.d/nerdctl
    - /etc/bash_completion.d/krew
    - /etc/bash_completion.d/krew.sh
    - "{{ krew_root_dir }}"
    - /etc/modules-load.d/kube_proxy-ipvs.conf
    - /etc/modules-load.d/kubespray-br_netfilter.conf
    - /etc/modules-load.d/kubespray-kata-containers.conf
    - /usr/libexec/kubernetes
    - /etc/origin/openvswitch
    - /etc/origin/ovn
    - "{{ sysctl_file_path }}"
    - /etc/crictl.yaml
  ignore_errors: true  # noqa ignore-errors
  tags:
    - files

- name: Reset | remove containerd binary files
  file:
    path: "{{ containerd_bin_dir }}/{{ item }}"
    state: absent
  with_items:
    - containerd
    - containerd-shim
    - containerd-shim-runc-v1
    - containerd-shim-runc-v2
    - containerd-stress
    - crictl
    - critest
    - ctd-decoder
    - ctr
    - runc
  ignore_errors: true  # noqa ignore-errors
  when: container_manager == 'containerd'
  tags:
    - files

- name: Reset | remove dns settings from dhclient.conf
  blockinfile:
    path: "{{ item }}"
    state: absent
    marker: "# Ansible entries {mark}"
  failed_when: false
  with_items:
    - /etc/dhclient.conf
    - /etc/dhcp/dhclient.conf
  tags:
    - files
    - dns

- name: Reset | remove host entries from /etc/hosts
  blockinfile:
    path: "/etc/hosts"
    state: absent
    marker: "# Ansible inventory hosts {mark}"
  tags:
    - files
    - dns

- name: Reset | include file with reset tasks specific to the network_plugin if exists
  include_role:
    name: "network_plugin/{{ kube_network_plugin }}"
    tasks_from: reset
  when:
    - kube_network_plugin in ['flannel', 'cilium', 'kube-router', 'calico']
  tags:
    - network

- name: Reset | Restart network
  service:
    name: "{{ reset_restart_network_service_name }}"
    state: restarted
  when:
    - ansible_os_family not in ["Flatcar", "Flatcar Container Linux by Kinvolk"]
    - reset_restart_network | bool
  tags:
    - services
    - network
