# Copyright 2022 Dell Inc. or its subsidiaries. All Rights Reserved.
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.
---

- name: Fetch the network interfaces in UP state in the system
  shell: set -o pipefail && ip a | awk '/state UP/{print $2}'
  register: nic_addr_up
  changed_when: false
  tags: init

### public network

- name: Assert public nic
  assert:
    that:
      - public_nic in nic_addr_up.stdout
    success_msg: "{{ success_msg_public_nic }}"
    fail_msg: "{{ fail_msg_public_nic }}"
  tags: [ validate, init ]

- name: Fetch the system public IP
  set_fact:
    public_ip: "{{ lookup('vars','ansible_'+public_nic).ipv4.address }}"
  tags: init

### management network

- block:
  - name: Assert management network nic
    assert:
      that:
        - mngmnt_network_nic in nic_addr_up.stdout
      success_msg: "{{ success_msg_mngmnt_network_nic }}"
      fail_msg: "{{ fail_msg_mngmnt_network_nic }}"
    tags: [ validate, network-device ]

  - name: Fetch the management network ip, netmask and subnet
    set_fact:
      mngmnt_network_ip: "{{ lookup('vars','ansible_'+mngmnt_network_nic).ipv4.address }}"
      mngmnt_network_netmask: "{{ lookup('vars','ansible_'+mngmnt_network_nic).ipv4.netmask }}"
      mngmnt_network_subnet: "{{ lookup('vars','ansible_'+mngmnt_network_nic).ipv4.network }}"
    tags: init

  - name: Check the subnet of management network dhcp start range
    shell: |
      IFS=. read -r i1 i2 i3 i4 <<< "{{ mngmnt_network_dhcp_start_range }}"
      IFS=. read -r m1 m2 m3 m4 <<< "{{ mngmnt_network_netmask }}"
      printf "%d.%d.%d.%d\n" "$((i1 & m1))" "$((i2 & m2))" "$((i3 & m3))" "$((i4 & m4))"
    args:
      warn: no
    register: dhcp_start_mgmnt_result
    changed_when: false
    tags: init

  - name: Set the start dhcp subnet for management network
    set_fact:
      dhcp_start_mgmnt: "{{ dhcp_start_mgmnt_result.stdout }}"
    tags: init

  - name: Check the subnet of dhcp end range for management network
    shell: |
      IFS=. read -r i1 i2 i3 i4 <<< "{{ mngmnt_network_dhcp_end_range }}"
      IFS=. read -r m1 m2 m3 m4 <<< "{{ mngmnt_network_netmask }}"
      printf "%d.%d.%d.%d\n" "$((i1 & m1))" "$((i2 & m2))" "$((i3 & m3))" "$((i4 & m4))"
    register: dhcp_end_mgmnt_result
    changed_when: false
    tags: init

  - name: Set the end dhcp subnet for management network
    set_fact:
      dhcp_end_mgmnt: "{{ dhcp_end_mgmnt_result.stdout }}"
    tags: init

  - name: Assert management_net_dhcp_start_range
    assert:
      that:
        - mngmnt_network_dhcp_start_range |  length > 1
        - mngmnt_network_dhcp_start_range | ipv4
        - mngmnt_network_dhcp_start_range != mngmnt_network_ip
        - mngmnt_network_dhcp_start_range != mngmnt_network_dhcp_end_range
        - dhcp_start_mgmnt == mngmnt_network_subnet
        - dhcp_start_mgmnt == dhcp_end_mgmnt
      success_msg: "{{ success_dhcp_range }} for management network"
      fail_msg: "{{ fail_dhcp_range }} for management network"
    tags: [ validate, network-device ]

  - name: Assert management_net_dhcp_end_range
    assert:
      that:
        - mngmnt_network_dhcp_end_range |  length > 1
        - mngmnt_network_dhcp_end_range | ipv4
        - mngmnt_network_dhcp_end_range != mngmnt_network_ip
        - mngmnt_network_dhcp_start_range != mngmnt_network_dhcp_end_range
        - dhcp_end_mgmnt == mngmnt_network_subnet
        - dhcp_start_mgmnt == dhcp_end_mgmnt
      success_msg: "{{ success_dhcp_range }} for management network"
      fail_msg: "{{ fail_dhcp_range }} for management network"
    tags: [ validate, network-device ]

  - name: Set the mapping file value for management network
    set_fact:
      mngmnt_mapping_file: true
    when: mngmnt_mapping_file_path | length > 0
    tags: init

  - name: Assert valid mngmnt_mapping_file_path
    stat:
      path: "{{ mngmnt_mapping_file_path }}"
    when: mngmnt_mapping_file
    register: result_mngmnt_mapping_file
    tags: init

  - name : Valid mngmnt_mapping_file_path
    fail:
      msg: "{{ invalid_mapping_file_path }} for management network"
    when: mngmnt_mapping_file and not result_mngmnt_mapping_file.stat.exists
    tags: init
  when: device_config_support

### host network

- name: Fetch the host network ip, netmask and subnet
  set_fact:
    hpc_ip: "{{ lookup('vars','ansible_'+host_network_nic).ipv4.address }}"
    netmask: "{{ lookup('vars','ansible_'+host_network_nic).ipv4.netmask }}"
    subnet: "{{ lookup('vars','ansible_'+host_network_nic).ipv4.network }}"
  tags: init

- name: Check the subnet of host network dhcp start range
  shell: |
    IFS=. read -r i1 i2 i3 i4 <<< "{{ host_network_dhcp_start_range }}"
    IFS=. read -r m1 m2 m3 m4 <<< "{{ netmask }}"
    printf "%d.%d.%d.%d\n" "$((i1 & m1))" "$((i2 & m2))" "$((i3 & m3))" "$((i4 & m4))"
  args:
    warn: no
  register: dhcp_start_host_result
  changed_when: false
  tags: init

- name: Set the start dhcp subnet for host network
  set_fact:
    dhcp_start_host: "{{ dhcp_start_host_result.stdout }}"
  tags: init

- name: Check the subnet of dhcp end range for host network
  shell: |
    IFS=. read -r i1 i2 i3 i4 <<< "{{ host_network_dhcp_end_range }}"
    IFS=. read -r m1 m2 m3 m4 <<< "{{ netmask }}"
    printf "%d.%d.%d.%d\n" "$((i1 & m1))" "$((i2 & m2))" "$((i3 & m3))" "$((i4 & m4))"
  register: dhcp_end_host_result
  changed_when: false
  tags: init

- name: Set the end dhcp subnet for host network
  set_fact:
    dhcp_end_host: "{{ dhcp_end_host_result.stdout }}"
  tags: init

- name: Assert host_network_dhcp_start_range
  assert:
    that:
      - host_network_dhcp_start_range | length > 1
      - host_network_dhcp_start_range | ipv4
      - host_network_dhcp_start_range != hpc_ip
      - host_network_dhcp_start_range != host_network_dhcp_end_range
      - dhcp_start_host == subnet
      - dhcp_start_host == dhcp_end_host
    success_msg: "{{ success_dhcp_range }} for host network"
    fail_msg: "{{ fail_dhcp_range }} for host network"
  tags: [ validate, pxe ]

- name: Assert host_network_dhcp_end_range
  assert:
    that:
      - host_network_dhcp_end_range | length > 1
      - host_network_dhcp_end_range | ipv4
      - host_network_dhcp_end_range != hpc_ip
      - host_network_dhcp_start_range != host_network_dhcp_end_range
      - dhcp_end_host == subnet
      - dhcp_start_host == dhcp_end_host
    success_msg: "{{ success_dhcp_range }} for host network"
    fail_msg: "{{ fail_dhcp_range }} for host network"
  tags: [ validate, pxe ]

- name: Set the mapping file value for host network
  set_fact:
    host_mapping_file: true
  when: host_mapping_file_path | length > 0
  tags: init

- name: Assert valid mapping_file_path
  stat:
    path: "{{ host_mapping_file_path }}"
  when: host_mapping_file
  register: result_host_mapping_file
  tags: init

- name: Valid mapping_file_path
  fail:
    msg: "{{ invalid_mapping_file_path }} for host_network"
  when: host_mapping_file and not result_host_mapping_file.stat.exists
  tags: init

- name: Verify different nics
  assert:
    that:
      - public_nic != mngmnt_network_nic
      - mngmnt_network_nic != host_network_nic
      - public_nic != host_network_nic
    success_msg: "{{ success_msg_different_nics }}"
    fail_msg: "{{ fail_msg_different_nics }}"
  when: device_config_support
  tags: [ validate, pxe, network-device ]

- name: Verify different nics
  assert:
    that:
      - public_nic != host_network_nic
    success_msg: "{{ success_msg_different_nics }}"
    fail_msg: "{{ fail_msg_different_nics }}"
  tags: [ validate, pxe ]

### ib network

- block:
    - name: Fetch the infiniband network ip, netmask and subnet
      set_fact:
        ib_ip: "{{ lookup('vars','ansible_'+ib_network_nic).ipv4.address }}"
        ib_netmask: "{{ lookup('vars','ansible_'+ib_network_nic).ipv4.netmask }}"
        ib_subnet: "{{ lookup('vars','ansible_'+ib_network_nic).ipv4.network }}"
      tags: init
      
    - name: Check the subnet of infiniband network dhcp start range
      shell: |
        IFS=. read -r i1 i2 i3 i4 <<< "{{ ib_network_dhcp_start_range }}"
        IFS=. read -r m1 m2 m3 m4 <<< "{{ ib_netmask }}"
        printf "%d.%d.%d.%d\n" "$((i1 & m1))" "$((i2 & m2))" "$((i3 & m3))" "$((i4 & m4))"
      args:
        warn: no
      register: dhcp_start_ib_result  
      changed_when: false
      tags: init

    - name: Set the start dhcp subnet for infiniband network
      set_fact:
        dhcp_start_ib: "{{ dhcp_start_ib_result.stdout }}"
      tags: init    

    - name: Check the subnet of dhcp end range for infiniband network
      shell: |
        IFS=. read -r i1 i2 i3 i4 <<< "{{ ib_network_dhcp_end_range }}"
        IFS=. read -r m1 m2 m3 m4 <<< "{{ ib_netmask }}"
        printf "%d.%d.%d.%d\n" "$((i1 & m1))" "$((i2 & m2))" "$((i3 & m3))" "$((i4 & m4))"
      register: dhcp_end_ib_result  
      changed_when: false
      tags: init

    - name: Set the end dhcp subnet for infiniband network
      set_fact:
        dhcp_end_ib: "{{ dhcp_end_ib_result.stdout }}"
      tags: init

    - name: Assert infiniband_net_dhcp_start_range
      assert:
        that:
          - ib_network_dhcp_start_range | length > 1
          - ib_network_dhcp_start_range | ipv4
          - ib_network_dhcp_start_range != ib_ip
          - ib_network_dhcp_start_range != ib_network_dhcp_end_range
          - dhcp_start_ib == ib_subnet
          - dhcp_start_ib == dhcp_end_ib
        success_msg: "{{ success_dhcp_range }} for infiniband network"
        fail_msg: "{{ fail_dhcp_range }} for infiniband network"
      tags: [ validate, network-ib ]
  
    - name: Assert infiniband_net_dhcp_end_range
      assert:
        that:
          - ib_network_dhcp_end_range | length > 1
          - ib_network_dhcp_end_range | ipv4
          - ib_network_dhcp_end_range != ib_ip
          - ib_network_dhcp_start_range != ib_network_dhcp_end_range
          - dhcp_end_ib == ib_subnet
          - dhcp_start_ib == dhcp_end_ib
        success_msg: "{{ success_dhcp_range }} for infiniband network"
        fail_msg: "{{ fail_dhcp_range }} for infiniband network"
      tags: [ validate, network-ib ]

    - name: Verify different nics with infiniband nic
      assert:
        that:
          - public_nic != ib_network_nic
          - mngmnt_network_nic != ib_network_nic
          - ib_network_nic != host_network_nic
        success_msg: "{{ success_msg_different_nics_ib }}"
        fail_msg: "{{ fail_msg_different_nics_ib }}"
      tags: [ validate, pxe, network-ib, network-device ]
  when: ib_switch_support