---
- name: Gather facts for localhost
  hosts: localhost
  gather_facts: true
  tags: always

- name: Validate configuration options for kolla-ansible
  hosts: localhost
  tags:
    - kolla-ansible
    - config-validation
  tasks:
    - name: Validate serial console configuration
      block:
        - name: Check ipmitool-socat is in kolla_ironic_enabled_console_interfaces
          assert:
            that:
              - kolla_ironic_enabled_console_interfaces is defined
              - "'ipmitool-socat' in kolla_ironic_enabled_console_interfaces"
            fail_msg: >
              kolla_ironic_enabled_console_interfaces must contain ipmitool-socat if you set
              ironic_serial_console_autoenable to true
      when: ironic_serial_console_autoenable | bool

- name: Ensure Kolla Ansible is configured
  hosts: localhost
  tags:
    - kolla-ansible
  gather_facts: false
  pre_tasks:
    - block:
        - name: Look for environment file in Kolla configuration path
          stat:
            path: "{{ kolla_config_path ~ '/.environment' }}"
            get_checksum: False
            mime: False
          register: kolla_environment_file

        - name: Flag that the Kolla configuration path has been used by another environment
          vars:
            kolla_environment: "{{ lookup('file', kolla_config_path ~ '/.environment') }}"
          fail:
            msg: >
              The Kolla configuration path at {{ kolla_config_path }} was
              already used by environment {{ kolla_environment }}. You should
              clean up this directory, including the environment file located
              at {{ kolla_config_path ~ '/.environment' }}, before running
              Kayobe again.
          when:
            - kolla_environment_file.stat.exists
            - kolla_environment != kayobe_environment

      tags:
        - config

    # Configuration and validation of network host networking.
    - name: Validate Kolla Ansible API address configuration
      assert:
        that:
          - hostvars[inventory_hostname][item.var_name] is defined
          - hostvars[inventory_hostname][item.var_name] | length > 0
        fail_msg: >
          The Kolla Ansible variable {{ item.var_name }}
          ({{ item.description }}) is invalid. Value:
          "{{ hostvars[inventory_hostname][item.var_name] | default('<undefined>') }}".
      when:
        - groups[controller_loadbalancer_group] | length > 0
        - item.required | bool
      with_items:
        - var_name: "kolla_internal_vip_address"
          description: "Internal API VIP address"
          required: True
        - var_name: "kolla_internal_fqdn"
          description: "Internal API Fully Qualified Domain Name (FQDN)"
          required: True
        - var_name: "kolla_external_vip_address"
          description: "external API VIP address"
          required: "{{ public_net_name != internal_net_name }}"
        - var_name: "kolla_external_fqdn"
          description: "External API Fully Qualified Domain Name (FQDN)"
          required: "{{ public_net_name != internal_net_name }}"
      tags:
        - config
        - config-validation

    - import_role:
        name: kolla-ansible
      vars:
        kolla_ansible_install_epel: "{{ dnf_install_epel }}"
        kolla_external_fqdn_cert: "{{ kolla_config_path }}/certificates/haproxy.pem"
        kolla_internal_fqdn_cert: "{{ kolla_config_path }}/certificates/haproxy-internal.pem"
        kolla_ansible_passwords_path: "{{ kayobe_env_config_path }}/kolla/passwords.yml"
        kolla_overcloud_inventory_search_paths_static:
          - "{{ kayobe_config_path }}"
        kolla_overcloud_inventory_search_paths: "{{ kolla_overcloud_inventory_search_paths_static + kayobe_env_search_paths }}"
        kolla_ansible_certificates_path: "{{ kayobe_env_config_path }}/kolla/certificates"
        kolla_inspector_dhcp_pool_start: "{{ inspection_net_name | net_inspection_allocation_pool_start }}"
        kolla_inspector_dhcp_pool_end: "{{ inspection_net_name | net_inspection_allocation_pool_end }}"
        kolla_inspector_netmask: "{{ inspection_net_name | net_mask }}"
        kolla_inspector_default_gateway: "{{ inspection_net_name | net_inspection_gateway or inspection_net_name | net_gateway }}"
        kolla_inspector_extra_kernel_options: "{{ inspector_extra_kernel_options }}"
        kolla_libvirt_tls: "{{ compute_libvirt_enable_tls | bool }}"
        kolla_globals_paths_static:
          - "{{ kayobe_config_path }}"
        kolla_globals_paths_extra: "{{ kolla_globals_paths_static + kayobe_env_search_paths }}"
        kolla_ironic_inspector_host: "{{ groups[controller_ironic_inspector_group][0] if groups[controller_ironic_inspector_group] | length > 0 else '' }}"

- name: Generate Kolla Ansible host vars for the seed host
  hosts: seed
  tags:
    - config
    - config-validation
    - kolla-ansible
  gather_facts: False
  tasks:
    - name: Set Kolla Ansible host variables
      kolla_ansible_host_vars:
        interfaces:
          - var_name: "kolla_bifrost_network_interface"
            description: "Bifrost provisioning network"
            network: "{{ provision_oc_net_name }}"
            required: True
          # Strictly api_interface is not required but kolla-ansible currently
          # references it in prechecks.
          - var_name: "kolla_api_interface"
            description: "Bifrost provisioning network"
            network: "{{ provision_oc_net_name }}"
            required: True

    - import_role:
        name: kolla-ansible-host-vars
      vars:
        kolla_ansible_pass_through_host_vars: "{{ kolla_seed_inventory_pass_through_host_vars }}"
        kolla_ansible_pass_through_host_vars_map: "{{ kolla_seed_inventory_pass_through_host_vars_map }}"
        kolla_ansible_inventory_path: "{{ kolla_config_path }}/inventory/seed"

- name: Generate Kolla Ansible host vars for overcloud hosts
  hosts: overcloud
  tags:
    - config
    - config-validation
    - kolla-ansible
  gather_facts: False
  tasks:
    - name: Set Kolla Ansible host variables
      vars:
        require_ironic_networks: >-
          {{ kolla_enable_ironic | bool and
             inventory_hostname in groups[controller_ironic_conductor_group] }}
        ironic_networks:
          - network: "{{ provision_wl_net_name }}"
            required: "{{ require_ironic_networks }}"
          - network: "{{ cleaning_net_name }}"
            required: "{{ require_ironic_networks }}"
        require_provider_networks: >-
          {{ kolla_enable_neutron | bool and
             (inventory_hostname in groups[controller_network_group] or
              (kolla_enable_neutron_provider_networks | bool and inventory_hostname in groups['compute'])) }}
        # This expression generates a list containing an item for each network
        # in external_net_names, in the format required by the
        # external_networks argument of the kolla_ansible_host_vars action
        # plugin.
        provider_networks: >-
          {{ dict(external_net_names |
                  zip_longest([], fillvalue=require_provider_networks)) |
             dict2items(key_name='network', value_name='required') }}
      kolla_ansible_host_vars:
        interfaces:
          - var_name: "kolla_network_interface"
            description: "Default network"
            network: "{{ internal_net_name }}"
            required: True
          - var_name: "kolla_api_interface"
            description: "API network"
            network: "{{ internal_net_name }}"
            required: True
          - var_name: "kolla_storage_interface"
            description: "Storage network"
            network: "{{ storage_net_name }}"
            required: False
          - var_name: "kolla_cluster_interface"
            description: "Cluster network"
            network: "{{ storage_mgmt_net_name }}"
            required: False
          - var_name: "kolla_swift_storage_interface"
            description: "Swift storage network"
            network: "{{ swift_storage_net_name }}"
            required: False
          - var_name: "kolla_swift_replication_interface"
            description: "Swift storage replication network"
            network: "{{ swift_storage_replication_net_name }}"
            required: False
          - var_name: "kolla_provision_interface"
            description: "Bare metal provisioning network"
            network: "{{ provision_wl_net_name }}"
            required: "{{ require_ironic_networks }}"
          - var_name: "kolla_inspector_dnsmasq_interface"
            description: "Bare metal introspection network"
            network: "{{ inspection_net_name }}"
            required: "{{ require_ironic_networks }}"
          - var_name: "kolla_dns_interface"
            description: "DNS network"
            network: "{{ public_net_name }}"
            required: False
          - var_name: "kolla_tunnel_interface"
            description: "Tunnel network"
            network: "{{ tunnel_net_name }}"
            required: False
          - var_name: "kolla_external_vip_interface"
            description: "External network"
            network: "{{ public_net_name }}"
            required: "{{ inventory_hostname in groups[controller_loadbalancer_group] }}"
        external_networks: "{{ ironic_networks + provider_networks }}"

    - import_role:
        name: kolla-ansible-host-vars
      vars:
        kolla_ansible_pass_through_host_vars: "{{ kolla_overcloud_inventory_pass_through_host_vars }}"
        kolla_ansible_pass_through_host_vars_map: "{{ kolla_overcloud_inventory_pass_through_host_vars_map }}"
        kolla_ansible_inventory_path: "{{ kolla_config_path }}/inventory/overcloud"
