---
# Tests interface_pci field, test must be used in VM
- name: Test interfaces with PCI ids
  hosts: all
  tags:
    # container builds have no PCI devices, so ethernet interface detection
    # won't find anything; so save ourselves the extra initial role invocation
    - tests::booted
  become: true
  roles:
    - linux-system-roles.firewall

  tasks:
    - name: Set expected backend
      set_fact:
        nftables_backend:
          "{{ true
            if ansible_distribution in ['RedHat', 'CentOS', 'Fedora']
            and ansible_distribution_major_version is version('8', '>=')
            else false }}"

    - name: Find ethernet interface
      shell: |
        set -euo pipefail
        I=$(find /sys/class/net -name 'e*' | head -n1)
        # containers only have virtual devices; for PCI we need a real one
        if [ -n "$I" ] && [ -e "$I/device/vendor" ]; then
          echo "$I"
        fi
      register: find_iface
      changed_when: false

    - name: Test interfaces with PCI ids
      # this can't be tested in containers or similar envs without any real
      # ethernet devices
      when: find_iface.stdout != ""
      block:
        - name: Determine interface vendor/product ID
          shell: |
            set -euo pipefail
            VID="$(sed 's/^0x//' < {{ find_iface.stdout | quote }}/device/vendor)"
            PID="$(sed 's/^0x//' < {{ find_iface.stdout | quote }}/device/device)"
            echo "$VID:$PID"
          register: pci_id
          changed_when: false

        - name: Add pci device ethernet controller
          include_role:
            name: linux-system-roles.firewall
          vars:
            firewall:
              zone: internal
              interface_pci_id: "{{ pci_id.stdout }}"
              state: enabled
              permanent: true

        - name: Add pci device again
          include_role:
            name: linux-system-roles.firewall
          vars:
            firewall:
              zone: internal
              interface_pci_id: "{{ pci_id.stdout }}"
              state: enabled
              permanent: true

        - name: Get nftable ruleset
          command: nft list ruleset
          register: nft_list
          changed_when: false
          when: nftables_backend | bool

        - name: Assert that interface is in nftable ruleset
          assert:
            that:
              - find_iface.stdout | basename in nft_list.stdout
              - pci_id.stdout | trim not in nft_list.stdout
          when: nftables_backend | bool

        - name: Get iptables ruleset
          command: iptables -S
          register: ipt_list
          changed_when: false
          when: not nftables_backend | bool

        - name: Assert that interface is in iptables ruleset
          assert:
            that:
              - find_iface.stdout | basename in ipt_list.stdout
              - pci_id.stdout | trim not in ipt_list.stdout
          when: not nftables_backend | bool

        - name: Remove interface from internal
          include_role:
            name: linux-system-roles.firewall
          vars:
            firewall:
              zone: internal
              interface_pci_id: "{{ pci_id.stdout }}"
              state: disabled
              permanent: true
      always:
        - name: Cleanup
          tags:
            - tests::cleanup
          include_role:
            name: linux-system-roles.firewall
          vars:
            firewall:
              - previous: replaced
