---
- name: Ensure networking is configured
  hosts: seed-hypervisor:seed:overcloud
  tags:
    - config
    - network
  vars:
    ether_interfaces: "{{ network_interfaces | net_select_ethers | list }}"
    bridge_interfaces: "{{ network_interfaces | net_select_bridges | list }}"
    bond_interfaces: "{{ network_interfaces | net_select_bonds | list }}"
  pre_tasks:
    - block:
        - name: Validate network interface configuration
          fail:
            msg: >
              Network interface validation failed - no interface configured for
              {{ item }}. This should be configured via '{{ item }}_interface'.
          with_items: "{{ ether_interfaces }}"
          when: not item | net_interface

        - name: Validate bridge interface configuration
          fail:
            msg: >
              Bridge interface validation failed - no interface configured for
              {{ item }}. This should be configured via '{{ item }}_interface'.
          with_items: "{{ bridge_interfaces }}"
          when: not item | net_interface

        - name: Validate bond interface configuration
          fail:
            msg: >
              Bond interface validation failed - no interface configured for
              {{ item }}. This should be configured via '{{ item }}_interface'.
          with_items: "{{ bond_interfaces }}"
          when: not item | net_interface
      tags:
        - config-validation

    - name: Ensure NetworkManager is disabled
      service:
        name: NetworkManager
        state: stopped
        enabled: no
      become: True
      register: nm_result
      failed_when:
        - nm_result is failed
        # Ugh, Ansible's service module doesn't handle uninstalled services.
        - "'Could not find the requested service' not in nm_result.msg"

  roles:
    - role: ahuffman.resolv
      when: resolv_is_managed | bool
      become: True

    - role: MichaelRigart.interfaces
      interfaces_route_tables: "{{ network_route_tables }}"
      interfaces_ether_interfaces: >
        {{ ether_interfaces |
           map('net_interface_obj') |
           list }}
      interfaces_bridge_interfaces: >
        {{ bridge_interfaces |
           map('net_bridge_obj') |
           list }}
      interfaces_bond_interfaces: >
        {{ bond_interfaces |
           map('net_bond_obj') |
           list }}
      become: True

# Configure virtual ethernet patch links to connect the workload provision
# and external network bridges to the Neutron OVS bridge.
- name: Ensure OVS patch links exist
  hosts: network:compute
  tags:
    - config
    - network
  vars:
    veth_bridge_mtu_map: {}
    veth_interfaces: []
  pre_tasks:
    # When these networks are VLANs, we need to use the underlying tagged
    # bridge interface rather than the untagged interface. We therefore strip
    # the .<vlan> suffix of the interface name. We use a union here as a single
    # tagged interface may be shared between these networks.
    - name: Update a fact containing bridges to be patched to the Neutron OVS bridge
      set_fact:
        veth_bridge_mtu_map: >
          {{ veth_bridge_mtu_map | combine({interface: mtu}) }}
      with_items: "{{ [provision_wl_net_name, cleaning_net_name] + external_net_names | unique | list }}"
      when: item in network_interfaces
      vars:
        interface: "{{ item | net_interface | replace('.' ~ item | net_vlan | default('!nomatch!'), '') }}"
        # Determine the MTU as the maximum of all subinterface MTUs. Only
        # interfaces with an explicit MTU set will be taken account of. If no
        # interface has an explicit MTU set, then the corresponding veth will
        # not either.
        mtu: "{{ [veth_bridge_mtu_map.get(interface), item | net_mtu] | max }}"

    - name: Update a fact containing veth interfaces
      set_fact:
        veth_interfaces: >
          {{ veth_interfaces +
             [{'device': network_patch_prefix ~ item.key ~ network_patch_suffix_phy,
               'bootproto': 'static',
               'bridge': item.key,
               'mtu': item.value,
               'peer_device': network_patch_prefix ~ item.key ~ network_patch_suffix_ovs,
               'peer_bootproto': 'static',
               'peer_mtu': item.value,
               'onboot': 'yes'}] }}
      with_dict: "{{ veth_bridge_mtu_map }}"
  roles:
    - role: veth
