---
- name: Check whether Ironic is enabled
  hosts: controllers
  tags:
    - provision-net
    - cleaning-net
  tasks:
    - name: Create controllers group with ironic enabled
      group_by:
        key: "controllers_for_provision_net_{{ kolla_enable_ironic | bool }}"

- name: Ensure provisioning and cleaning networks and subnets are registered in neutron
  # Only required to run on a single host.
  hosts: controllers_for_provision_net_True[0]
  gather_facts: False
  vars:
    venv: "{{ virtualenv_path }}/shade"
    provision_net:
      name: "{{ kolla_ironic_provisioning_network }}"
      provider_network_type: "{% if provision_wl_net_name | net_vlan %}vlan{% else %}flat{% endif %}"
      provider_physical_network: "{{ provision_wl_net_name | net_physical_network | default('physnet1', True) }}"
      provider_segmentation_id: "{{ provision_wl_net_name | net_vlan }}"
      # Flat networks need to be shared to allow instances to use them.
      shared: "{{ (provision_wl_net_name | net_vlan) is none }}"
      subnets:
        - name: "{{ kolla_ironic_provisioning_network }}"
          cidr: "{{ provision_wl_net_name | net_cidr }}"
          gateway_ip: "{{ provision_wl_net_name | net_neutron_gateway or provision_wl_net_name | net_gateway }}"
          allocation_pool_start: "{{ provision_wl_net_name | net_neutron_allocation_pool_start }}"
          allocation_pool_end: "{{ provision_wl_net_name | net_neutron_allocation_pool_end }}"
    cleaning_net:
      name: "{{ kolla_ironic_cleaning_network }}"
      provider_network_type: "{% if cleaning_net_name | net_vlan %}vlan{% else %}flat{% endif %}"
      provider_physical_network: "{{ cleaning_net_name | net_physical_network | default('physnet1', True) }}"
      provider_segmentation_id: "{{ cleaning_net_name | net_vlan }}"
      # Flat networks need to be shared to allow instances to use them.
      shared: "{{ (cleaning_net_name | net_vlan) is none }}"
      subnets:
        - name: "{{ kolla_ironic_cleaning_network }}"
          cidr: "{{ cleaning_net_name | net_cidr }}"
          gateway_ip: "{{ cleaning_net_name | net_neutron_gateway or cleaning_net_name | net_gateway }}"
          allocation_pool_start: "{{ cleaning_net_name | net_neutron_allocation_pool_start }}"
          allocation_pool_end: "{{ cleaning_net_name | net_neutron_allocation_pool_end }}"
    network_registrations: "{{ [provision_net] + ([] if cleaning_net_name == provision_wl_net_name else [cleaning_net]) }}"
  tags:
    - provision-net
    - cleaning-net
  pre_tasks:
    - name: Validate OpenStack password authentication parameters
      fail:
        msg: >
          Required OpenStack authentication parameter {{ item }} is
          {% if item in openstack_auth %}empty{% else %}not present{% endif %}
          in openstack_auth. Have you sourced the environment file?
      when:
        - openstack_auth_type == 'password'
        - item not in openstack_auth or not openstack_auth[item]
      with_items: "{{ openstack_auth_password_required_params }}"
      tags:
        - config-validation

  roles:
    - role: stackhpc.os-networks
      os_shade_install_epel: "{{ yum_install_epel }}"
      os_shade_state: latest
      os_shade_upper_constraints_file: "{{ pip_upper_constraints_file }}"
      os_networks_venv: "{{ venv }}"
      os_networks_auth_type: "{{ openstack_auth_type }}"
      os_networks_auth: "{{ openstack_auth }}"
      os_networks_cacert: "{{ openstack_cacert | default(omit, true) }}"
      os_networks_interface: "{{ openstack_interface | default(omit, true) }}"
      # Network configuration.
      os_networks: "{{ network_registrations }}"
  tasks:
    # NOTE(mgoddard): Originally, provisioning and cleaning networks were
    # always shared. However now, VLAN networks are not shared. The os_network
    # module does not appear to update networks after they have been created,
    # so during this transition we manually update them here if necessary.
    # TODO(mgoddard): Remove this code after a suitable transition period.

    - import_role:
        role: activate-virtualenv
      vars:
        activate_virtualenv_path: "{{ venv }}"

    - name: Ensure python-openstackclient is installed
      pip:
        name: python-openstackclient
        state: latest
        extra_args: "{% if pip_upper_constraints_file %}-c {{ pip_upper_constraints_file }}{% endif %}"
        virtualenv: "{{ venv }}"
      when: network_registrations | rejectattr('shared') | list | length > 0

    - block:
        - name: Gather facts about provisioning network
          os_networks_facts:
            auth: "{{ openstack_auth }}"
            auth_type: "{{ openstack_auth_type }}"
            cacert: "{{ openstack_cacert | default(omit, true) }}"
            interface: "{{ openstack_interface | default(omit, true) }}"
            name: "{{ provision_net.name }}"
          register: provisioning_network_facts

        - name: Set provisioning network to unshared
          command: "{{ venv }}/bin/openstack network set {{ provision_net.name }} --no-share"
          changed_when: true
          when: openstack_networks[0].shared
          environment: "{{ openstack_auth_env }}"
      when: not provision_net.shared | bool

    - block:
        - name: Gather facts about cleaning network
          os_networks_facts:
            auth: "{{ openstack_auth }}"
            auth_type: "{{ openstack_auth_type }}"
            cacert: "{{ openstack_cacert | default(omit, true) }}"
            interface: "{{ openstack_interface | default(omit, true) }}"
            name: "{{ cleaning_net.name }}"
          register: cleaning_network_facts

        - name: Set cleaning network to unshared
          command: "{{ venv }}/bin/openstack network set {{ cleaning_net.name }} --no-share"
          changed_when: true
          when: openstack_networks[0].shared
          environment: "{{ openstack_auth_env }}"
      when:
        - cleaning_net_name != provision_wl_net_name
        - not cleaning_net.shared | bool

    - import_role:
        role: deactivate-virtualenv
