---
- name: Testcases for network
  hosts: kube_control_plane[0]
  vars:
    test_image_repo: registry.k8s.io/e2e-test-images/agnhost
    test_image_tag: "2.40"
    # TODO: source those from kubespray-defaults instead.
    # Needs kubespray-defaults to be decoupled from no-proxy stuff
    bin_dir: "/usr/local/bin"
    kube_pods_subnet: 10.233.64.0/18

  tasks:

  - name: Check kubelet serving certificates approved with kubelet_csr_approver
    when:
    - kubelet_rotate_server_certificates | default(false)
    - kubelet_csr_approver_enabled | default(kubelet_rotate_server_certificates | default(false))
    vars:
      csrs: "{{ csr_json.stdout | from_json }}"
    block:

    - name: Get certificate signing requests
      command: "{{ bin_dir }}/kubectl get csr -o jsonpath-as-json={.items[*]}"
      register: csr_json
      changed_when: false

    - name: Check there are csrs
      assert:
        that: csrs | length > 0
        fail_msg: kubelet_rotate_server_certificates is {{ kubelet_rotate_server_certificates }} but no csr's found

    - name: Check there are Denied/Pending csrs
      assert:
        that:
        - csrs | rejectattr('status') | length == 0 # Pending == no status
        - csrs | map(attribute='status.conditions') | flatten | selectattr('type', 'equalto', 'Denied') | length == 0 # Denied

        fail_msg: kubelet_csr_approver is enabled but CSRs are not approved

  - name: Approve kubelet serving certificates
    when:
    - kubelet_rotate_server_certificates | default(false)
    - not (kubelet_csr_approver_enabled | default(kubelet_rotate_server_certificates | default(false)))
    block:

    - name: Get certificate signing requests
      command: "{{ bin_dir }}/kubectl get csr -o name"
      register: get_csr
      changed_when: false

    - name: Check there are csrs
      assert:
        that: get_csr.stdout_lines | length > 0
        fail_msg: kubelet_rotate_server_certificates is {{ kubelet_rotate_server_certificates }} but no csr's found

    - name: Approve certificates
      command: "{{ bin_dir }}/kubectl certificate approve {{ get_csr.stdout_lines | join(' ') }}"
      register: certificate_approve
      when: get_csr.stdout_lines | length > 0
      changed_when: certificate_approve.stdout

  - name: Create test namespace
    command: "{{ bin_dir }}/kubectl create namespace test"
    changed_when: false

  - name: Run 2 agnhost pods in test ns
    command:
      cmd: "{{ bin_dir }}/kubectl apply --namespace test -f -"
      stdin: |
        apiVersion: apps/v1
        kind: Deployment
        metadata:
          name: agnhost
        spec:
          replicas: 2
          selector:
            matchLabels:
              app: agnhost
          template:
            metadata:
              labels:
                app: agnhost
            spec:
              containers:
              - name: agnhost
                image: {{ test_image_repo }}:{{ test_image_tag }}
                command: ['/agnhost', 'netexec', '--http-port=8080']
                securityContext:
                  allowPrivilegeEscalation: false
                  capabilities:
                    drop: ['ALL']
                  runAsUser: 1000
                  runAsNonRoot: true
                  seccompProfile:
                    type: RuntimeDefault
    changed_when: false

  - name: Check that all pods are running and ready
    vars:
      pods: "{{ (pods_json.stdout | from_json)['items'] }}"
    block:
    - name: Check Deployment is ready
      command: "{{ bin_dir }}/kubectl rollout status deploy --namespace test agnhost --timeout=180s"
      changed_when: false
    - name: Get pod names
      command: "{{ bin_dir }}/kubectl get pods -n test -o json"
      changed_when: false
      register: pods_json

    - name: Check pods IP are in correct network
      assert:
        that: pods
              | selectattr('status.phase', '==', 'Running')
              | selectattr('status.podIP', 'ansible.utils.in_network', kube_pods_subnet)
              | length == 2

    - name: Curl between pods is working
      command: "{{ bin_dir }}/kubectl -n test exec {{ item[0].metadata.name }} -- curl {{ item[1].status.podIP }}:8080"
      with_nested:
      - "{{ pods }}"
      - "{{ pods }}"
    rescue:
    - name: List pods cluster-wide
      command: "{{ bin_dir }}/kubectl get pods --all-namespaces -owide"
      changed_when: false

    - import_role:  # noqa name[missing]
        name: cluster-dump
    - fail: # noqa name[missing]
