Use host vars files for kolla ansible inventory
Kayobe writes out several host variables to the Kolla ansible inventory files, etc/kolla/inventory/seed and etc/kolla/inventory/overcloud. These include ansible_host, and network interfaces such as api_interface, ironic_dnsmasq_interface, etc. In Ansible, these should have a higher precedence than the kolla ansible group variables in ansible/group_vars/all.yml that set the defaults. However, in Ansible 2.4+, if the host has the same name as a group that it is in, the group variables now take precedence, meaning that it is not possible to override them. This was observed when using the kayobe-config-dev repo for testing, where the seed host is in the seed group. Admittedly ansible does tell you not to do this: [WARNING]: Found both group and host with same name: localhost The solution used here is to use a separate host_vars file for each host. Alternatively we could enforce that hostnames and groups do not overlap. Change-Id: I349c8279d85a591689ac8108bce14d96889440fe Story: 2004418 Task: 28065
This commit is contained in:
parent
62aa5d015f
commit
8dc7ba7889
@ -1,4 +1,31 @@
|
||||
---
|
||||
# NOTE: We're not looping over the two inventory files to avoid having the file
|
||||
# content displayed in the ansible-playbook output.
|
||||
|
||||
- name: Check whether the legacy Kolla overcloud inventory files exist
|
||||
stat:
|
||||
path: "{{ item }}"
|
||||
get_attributes: no
|
||||
get_checksum: no
|
||||
get_mime: no
|
||||
register: inventory_stat
|
||||
with_items:
|
||||
- "{{ kolla_seed_inventory_path }}"
|
||||
- "{{ kolla_overcloud_inventory_path }}"
|
||||
loop_control:
|
||||
label: "{{ item | basename }}"
|
||||
|
||||
- name: Ensure the legacy Kolla overcloud inventory file is absent
|
||||
file:
|
||||
path: "{{ item.item }}"
|
||||
state: absent
|
||||
with_items: "{{ inventory_stat.results }}"
|
||||
when:
|
||||
- item.stat.exists
|
||||
- item.stat.isreg
|
||||
loop_control:
|
||||
label: "{{ item.item | basename }}"
|
||||
|
||||
- name: Ensure the Kolla Ansible configuration directories exist
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
@ -9,7 +36,8 @@
|
||||
become: True
|
||||
with_items:
|
||||
- "{{ kolla_config_path }}"
|
||||
- "{{ kolla_config_path }}/inventory"
|
||||
- "{{ kolla_seed_inventory_path }}/host_vars"
|
||||
- "{{ kolla_overcloud_inventory_path }}/host_vars"
|
||||
- "{{ kolla_node_custom_config_path }}"
|
||||
|
||||
- name: Ensure the Kolla global configuration file exists
|
||||
@ -18,21 +46,42 @@
|
||||
dest: "{{ kolla_config_path }}/globals.yml"
|
||||
mode: 0640
|
||||
|
||||
# NOTE: We're not looping over the two inventory files to avoid having the file
|
||||
# content displayed in the ansible-playbook output.
|
||||
|
||||
- name: Ensure the Kolla seed inventory file exists
|
||||
copy:
|
||||
content: "{{ kolla_seed_inventory }}"
|
||||
dest: "{{ kolla_config_path }}/inventory/seed"
|
||||
dest: "{{ kolla_seed_inventory_path }}/hosts"
|
||||
mode: 0640
|
||||
|
||||
- name: Ensure the Kolla seed host vars files exist
|
||||
template:
|
||||
src: host-vars.j2
|
||||
dest: "{{ kolla_seed_inventory_path }}/host_vars/{{ host }}"
|
||||
mode: 0640
|
||||
with_inventory_hostnames: "seed"
|
||||
vars:
|
||||
host_vars: "{{ kolla_seed_inventory_pass_through_host_vars }}"
|
||||
host_vars_map: "{{ kolla_seed_inventory_pass_through_host_vars_map }}"
|
||||
loop_control:
|
||||
loop_var: host
|
||||
|
||||
- name: Ensure the Kolla overcloud inventory file exists
|
||||
copy:
|
||||
content: "{{ kolla_overcloud_inventory }}"
|
||||
dest: "{{ kolla_config_path }}/inventory/overcloud"
|
||||
dest: "{{ kolla_overcloud_inventory_path }}/hosts"
|
||||
mode: 0640
|
||||
|
||||
- name: Ensure the Kolla overcloud host vars files exist
|
||||
template:
|
||||
src: host-vars.j2
|
||||
dest: "{{ kolla_overcloud_inventory_path }}/host_vars/{{ host }}"
|
||||
mode: 0640
|
||||
with_inventory_hostnames: "{{ kolla_overcloud_top_level_groups }}"
|
||||
vars:
|
||||
host_vars: "{{ kolla_overcloud_inventory_pass_through_host_vars }}"
|
||||
host_vars_map: "{{ kolla_overcloud_inventory_pass_through_host_vars_map }}"
|
||||
loop_control:
|
||||
loop_var: host
|
||||
|
||||
- name: Ensure the Kolla passwords file exists
|
||||
kolla_passwords:
|
||||
src: "{{ kolla_ansible_passwords_path }}"
|
||||
|
7
ansible/roles/kolla-ansible/templates/host-vars.j2
Normal file
7
ansible/roles/kolla-ansible/templates/host-vars.j2
Normal file
@ -0,0 +1,7 @@
|
||||
---
|
||||
{% for hv_name in host_vars %}
|
||||
{% set host_hv=hostvars[host] %}
|
||||
{% if hv_name in host_hv %}
|
||||
{{ host_vars_map.get(hv_name, hv_name) }}: {{ host_hv[hv_name] | to_json }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
@ -4,26 +4,17 @@
|
||||
# Components define groups of services, e.g. nova or ironic.
|
||||
# Services define single containers, e.g. nova-compute or ironic-api.
|
||||
|
||||
{% set top_level_groups = kolla_overcloud_inventory_top_level_group_map.values() |
|
||||
selectattr('groups', 'defined') |
|
||||
map(attribute='groups') |
|
||||
sum(start=[]) |
|
||||
unique |
|
||||
list %}
|
||||
|
||||
{% for group in top_level_groups %}
|
||||
{% for group in kolla_overcloud_top_level_groups %}
|
||||
# Top level {{ group }} group.
|
||||
[{{ group }}]
|
||||
# These hostnames must be resolvable from your deployment host
|
||||
{% for host in groups.get(group, []) %}
|
||||
{% set host_hv=hostvars[host] %}
|
||||
{{ host }}{% for hv_name in kolla_overcloud_inventory_pass_through_host_vars %}{% if hv_name in host_hv %} {{ kolla_overcloud_inventory_pass_through_host_vars_map.get(hv_name, hv_name) }}='{{ host_hv[hv_name] | to_json }}'{% endif %}{% endfor %}
|
||||
|
||||
{{ host }}
|
||||
{% endfor %}
|
||||
|
||||
{% endfor %}
|
||||
[overcloud:children]
|
||||
{% for group in top_level_groups %}
|
||||
{% for group in kolla_overcloud_top_level_groups %}
|
||||
{{ group }}
|
||||
{% endfor %}
|
||||
|
||||
|
@ -1,9 +1,7 @@
|
||||
# Simple inventory for bootstrapping Kolla seed node.
|
||||
[seed]
|
||||
{% for seed in groups.get('seed', []) %}
|
||||
{% set seed_hv=hostvars[seed] %}
|
||||
{{ seed }}{% for hv_name in kolla_seed_inventory_pass_through_host_vars %}{% if hv_name in seed_hv %} {{ kolla_seed_inventory_pass_through_host_vars_map.get(hv_name, hv_name) }}='{{ seed_hv[hv_name] | to_json }}'{% endif %}{% endfor %}
|
||||
|
||||
{{ seed }}
|
||||
{% endfor %}
|
||||
|
||||
[seed:vars]
|
||||
|
@ -1,7 +1,5 @@
|
||||
---
|
||||
# TODO:
|
||||
# - Check inventory file.
|
||||
# - Add hosts to inventory.
|
||||
# - Seed custom inventory
|
||||
# - Overcloud custom inventory
|
||||
# - Group map
|
||||
|
@ -123,7 +123,9 @@
|
||||
path: "{{ temp_path ~ '/etc/kolla/inventory/' ~ item }}"
|
||||
with_items:
|
||||
- seed
|
||||
- seed/host_vars
|
||||
- overcloud
|
||||
- overcloud/host_vars
|
||||
register: inventory_stat
|
||||
|
||||
- name: Validate inventory files
|
||||
|
@ -371,7 +371,7 @@
|
||||
|
||||
- name: Check whether inventory files exist
|
||||
stat:
|
||||
path: "{{ temp_path ~ '/etc/kolla/inventory/' ~ item }}"
|
||||
path: "{{ temp_path ~ '/etc/kolla/inventory/' ~ item ~ '/hosts' }}"
|
||||
with_items:
|
||||
- seed
|
||||
- overcloud
|
||||
@ -398,7 +398,7 @@
|
||||
assert:
|
||||
that: item in inventory_lines
|
||||
with_items:
|
||||
- test-seed ansible_host='"1.2.3.4"' api_interface='"eth0"' bifrost_network_interface='"eth1"'
|
||||
- test-seed
|
||||
|
||||
- name: Validate overcloud inventory file contents
|
||||
vars:
|
||||
@ -406,8 +406,72 @@
|
||||
assert:
|
||||
that: item in inventory_lines
|
||||
with_items:
|
||||
- test-controller ansible_host='"1.2.3.5"' network_interface='"eth0"' api_interface='"eth2"' storage_interface='"eth3"' cluster_interface='"eth4"' provision_interface='"eth8"' ironic_dnsmasq_interface='"eth9"' dns_interface='"eth5"' tunnel_interface='"eth10"' kolla_external_vip_interface='"eth1"' neutron_external_interface='"eth6,eth7"' neutron_bridge_name='"br0,br1"'
|
||||
- test-compute ansible_host='"1.2.3.6"' network_interface='"eth0"' api_interface='"eth2"' storage_interface='"eth3"' tunnel_interface='"eth6"' neutron_external_interface='"eth4,eth5"' neutron_bridge_name='"br0,br1"'
|
||||
- test-controller
|
||||
- test-compute
|
||||
|
||||
- name: Check whether inventory host vars files exist
|
||||
stat:
|
||||
path: "{{ temp_path ~ '/etc/kolla/inventory/' ~ item }}"
|
||||
with_items:
|
||||
- seed/host_vars/test-seed
|
||||
- overcloud/host_vars/test-controller
|
||||
- overcloud/host_vars/test-compute
|
||||
register: host_vars_stat
|
||||
|
||||
- name: Validate inventory host vars files
|
||||
assert:
|
||||
that:
|
||||
- item.stat.exists
|
||||
- item.stat.size > 0
|
||||
msg: >
|
||||
Inventory file {{ item.item }} was not found.
|
||||
with_items: "{{ host_vars_stat.results }}"
|
||||
|
||||
- name: Read inventory host vars files
|
||||
slurp:
|
||||
src: "{{ item.stat.path }}"
|
||||
with_items: "{{ host_vars_stat.results }}"
|
||||
register: host_vars_slurp
|
||||
|
||||
- name: Validate inventory host vars file contents
|
||||
assert:
|
||||
that:
|
||||
- host_vars_content is defined
|
||||
- host_vars_content == item.1
|
||||
with_together:
|
||||
- "{{ host_vars_slurp.results }}"
|
||||
- "{{ expected_contents }}"
|
||||
vars:
|
||||
host_vars_content: "{{ item.0.content | b64decode }}"
|
||||
expected_contents:
|
||||
- |
|
||||
---
|
||||
ansible_host: "1.2.3.4"
|
||||
api_interface: "eth0"
|
||||
bifrost_network_interface: "eth1"
|
||||
- |
|
||||
---
|
||||
ansible_host: "1.2.3.5"
|
||||
network_interface: "eth0"
|
||||
api_interface: "eth2"
|
||||
storage_interface: "eth3"
|
||||
cluster_interface: "eth4"
|
||||
provision_interface: "eth8"
|
||||
ironic_dnsmasq_interface: "eth9"
|
||||
dns_interface: "eth5"
|
||||
tunnel_interface: "eth10"
|
||||
kolla_external_vip_interface: "eth1"
|
||||
neutron_external_interface: "eth6,eth7"
|
||||
neutron_bridge_name: "br0,br1"
|
||||
- |
|
||||
---
|
||||
ansible_host: "1.2.3.6"
|
||||
network_interface: "eth0"
|
||||
api_interface: "eth2"
|
||||
storage_interface: "eth3"
|
||||
tunnel_interface: "eth6"
|
||||
neutron_external_interface: "eth4,eth5"
|
||||
neutron_bridge_name: "br0,br1"
|
||||
|
||||
always:
|
||||
- name: Ensure the temporary directory is removed
|
||||
|
@ -51,6 +51,21 @@ kolla_overcloud_inventory_default: |
|
||||
# of the top level, component, and service inventories.
|
||||
kolla_overcloud_inventory: "{{ kolla_overcloud_inventory_custom or kolla_overcloud_inventory_default }}"
|
||||
|
||||
# List of names of all top level groups in the inventory.
|
||||
kolla_overcloud_top_level_groups: >
|
||||
{{ kolla_overcloud_inventory_top_level_group_map.values() |
|
||||
selectattr('groups', 'defined') |
|
||||
map(attribute='groups') |
|
||||
sum(start=[]) |
|
||||
unique |
|
||||
list }}
|
||||
|
||||
# Path to the kolla ansible seed inventory directory.
|
||||
kolla_seed_inventory_path: "{{ kolla_config_path }}/inventory/seed"
|
||||
|
||||
# Path to the kolla ansible overcloud inventory directory.
|
||||
kolla_overcloud_inventory_path: "{{ kolla_config_path }}/inventory/overcloud"
|
||||
|
||||
###############################################################################
|
||||
# Feature configuration.
|
||||
|
||||
|
@ -87,8 +87,13 @@ def _validate_args(parsed_args, inventory_filename):
|
||||
sys.exit(1)
|
||||
|
||||
inventory = _get_inventory_path(parsed_args, inventory_filename)
|
||||
result = utils.is_readable_file(inventory)
|
||||
result = utils.is_readable_dir(parsed_args.kolla_venv)
|
||||
if not result["result"]:
|
||||
# NOTE(mgoddard): Previously the inventory was a file, now it is a
|
||||
# directory to allow us to support inventory host_vars. Support both
|
||||
# formats for now.
|
||||
result_f = utils.is_readable_file(inventory)
|
||||
if not result_f["result"]:
|
||||
LOG.error("Kolla inventory %s is invalid: %s",
|
||||
inventory, result["message"])
|
||||
sys.exit(1)
|
||||
|
@ -0,0 +1,7 @@
|
||||
---
|
||||
fixes:
|
||||
- |
|
||||
Fixes an issue where if a host has the same name as a group that it is in,
|
||||
configuration of kolla ansible inventory host variables could fail to
|
||||
override the defaults. See `story 2004418
|
||||
<https://storyboard.openstack.org/#!/story/2004418>`__ for details.
|
Loading…
Reference in New Issue
Block a user