Add lxc_host dynamic group to inventory.
Previously, it was difficult to target only the hosts holding LXC
containers. This change will add a host to the implicit 'lxc_hosts'
group any time a container is created in association with that host.
Users cannot define this group in their configuration. Doing so will
result in an runtime error.
This approach allows for specific targeting without using complicated
Jinja calculations as seen in commit
76695012e6
. As such, the work in that
review has been replaced with this change.
Change-Id: I10faf5880a61abcc77f017573e0fd76d033224eb
This commit is contained in:
parent
5c2f0b4560
commit
518fb381c4
@ -142,6 +142,15 @@ Use the host's name as an argument.
|
|||||||
|
|
||||||
.. _`dynamic inventory functionality`: http://docs.ansible.com/ansible/intro_dynamic_inventory.html
|
.. _`dynamic inventory functionality`: http://docs.ansible.com/ansible/intro_dynamic_inventory.html
|
||||||
|
|
||||||
|
The lxc_hosts Group
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
When a container name is created by the dynamic inventory script, the host on
|
||||||
|
which the container resides is added to the ``lxc_hosts`` inventory group.
|
||||||
|
|
||||||
|
Using this name for a group in the configuration will result in a runtime
|
||||||
|
error.
|
||||||
|
|
||||||
Dynamic Inventory API documentation
|
Dynamic Inventory API documentation
|
||||||
-----------------------------------
|
-----------------------------------
|
||||||
|
|
||||||
|
@ -1,36 +0,0 @@
|
|||||||
---
|
|
||||||
# Copyright 2016, Rackspace US, Inc.
|
|
||||||
#
|
|
||||||
# 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: Generate container host list
|
|
||||||
hosts: localhost
|
|
||||||
connection: local
|
|
||||||
gather_facts: false
|
|
||||||
tasks:
|
|
||||||
- name: Create known container hosts fact
|
|
||||||
set_fact:
|
|
||||||
_known_container_hosts: >
|
|
||||||
{% set _var = [] -%}
|
|
||||||
{% for item in groups['all_containers'] -%}
|
|
||||||
{% if hostvars[item]['physical_host'] | default(false) != item -%}
|
|
||||||
{% if _var.append(hostvars[item]['physical_host']) -%}
|
|
||||||
{% endif -%}
|
|
||||||
{% endif -%}
|
|
||||||
{% endfor -%}
|
|
||||||
{{ _var | unique }}
|
|
||||||
- name: Create dynamic lxc_host group
|
|
||||||
add_host:
|
|
||||||
hostname: "{{ item }}"
|
|
||||||
groups: "known_container_hosts"
|
|
||||||
with_items: "{{ _known_container_hosts }}"
|
|
@ -115,6 +115,12 @@ class MissingStaticRouteInfo(Exception):
|
|||||||
return self.message
|
return self.message
|
||||||
|
|
||||||
|
|
||||||
|
class LxcHostsDefined(Exception):
|
||||||
|
def __init__(self):
|
||||||
|
self.message = ("The group 'lxc_hosts' must not be defined in config;"
|
||||||
|
" it will be dynamically generated.")
|
||||||
|
|
||||||
|
|
||||||
def args(arg_list):
|
def args(arg_list):
|
||||||
"""Setup argument Parsing."""
|
"""Setup argument Parsing."""
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
@ -371,6 +377,8 @@ def _add_container_hosts(assignment, config, container_name, container_type,
|
|||||||
# If host_type is not in config do not append containers to it
|
# If host_type is not in config do not append containers to it
|
||||||
if host_type not in config[physical_host_type]:
|
if host_type not in config[physical_host_type]:
|
||||||
continue
|
continue
|
||||||
|
append_if(array=inventory['lxc_hosts']['hosts'],
|
||||||
|
item=host_type)
|
||||||
|
|
||||||
# Get any set host options
|
# Get any set host options
|
||||||
host_options = config[physical_host_type][host_type]
|
host_options = config[physical_host_type][host_type]
|
||||||
@ -694,6 +702,8 @@ def container_skel_load(container_skel, inventory, config):
|
|||||||
:param inventory: ``dict`` Living dictionary of inventory
|
:param inventory: ``dict`` Living dictionary of inventory
|
||||||
:param config: ``dict`` User defined information
|
:param config: ``dict`` User defined information
|
||||||
"""
|
"""
|
||||||
|
if 'lxc_hosts' not in inventory.keys():
|
||||||
|
inventory['lxc_hosts'] = {'hosts': []}
|
||||||
for key, value in container_skel.iteritems():
|
for key, value in container_skel.iteritems():
|
||||||
contains_in = value.get('contains', False)
|
contains_in = value.get('contains', False)
|
||||||
belongs_to_in = value.get('belongs_to', False)
|
belongs_to_in = value.get('belongs_to', False)
|
||||||
@ -960,6 +970,11 @@ def _check_multiple_ips_to_host(config):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def _check_lxc_hosts(config):
|
||||||
|
if 'lxc_hosts' in config.keys():
|
||||||
|
raise LxcHostsDefined()
|
||||||
|
|
||||||
|
|
||||||
def _check_config_settings(cidr_networks, config, container_skel):
|
def _check_config_settings(cidr_networks, config, container_skel):
|
||||||
"""check preciseness of config settings
|
"""check preciseness of config settings
|
||||||
|
|
||||||
@ -1012,6 +1027,8 @@ def _check_config_settings(cidr_networks, config, container_skel):
|
|||||||
|
|
||||||
_check_multiple_ips_to_host(config)
|
_check_multiple_ips_to_host(config)
|
||||||
|
|
||||||
|
_check_lxc_hosts(config)
|
||||||
|
|
||||||
|
|
||||||
def load_environment(config_path, environment):
|
def load_environment(config_path, environment):
|
||||||
"""Create an environment dictionary from config files
|
"""Create an environment dictionary from config files
|
||||||
|
@ -13,10 +13,8 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
- include: common-plays/generate-lxc-container-hosts.yml
|
|
||||||
|
|
||||||
- name: Basic lxc host setup
|
- name: Basic lxc host setup
|
||||||
hosts: "{{ lxc_host_group | default('known_container_hosts') }}"
|
hosts: "{{ lxc_host_group | default('lxc_hosts')}}"
|
||||||
gather_facts: "{{ gather_facts | default(True) }}"
|
gather_facts: "{{ gather_facts | default(True) }}"
|
||||||
max_fail_percentage: 20
|
max_fail_percentage: 20
|
||||||
user: root
|
user: root
|
||||||
|
6
releasenotes/notes/lxc_hosts-group-a5643e7010d6b151.yaml
Normal file
6
releasenotes/notes/lxc_hosts-group-a5643e7010d6b151.yaml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- The inventory script will now dynamically populate the ``lxc_hosts`` group
|
||||||
|
dynamically based on which machines have container affinities defined.
|
||||||
|
|
||||||
|
This group is not allowed in user-defined configuration.
|
@ -153,6 +153,7 @@ class TestAnsibleInventoryFormatConstraints(unittest.TestCase):
|
|||||||
'log_all',
|
'log_all',
|
||||||
'log_containers',
|
'log_containers',
|
||||||
'log_hosts',
|
'log_hosts',
|
||||||
|
'lxc_hosts',
|
||||||
'magnum',
|
'magnum',
|
||||||
'magnum_all',
|
'magnum_all',
|
||||||
'magnum_container',
|
'magnum_container',
|
||||||
@ -403,6 +404,11 @@ class TestConfigCheckBase(unittest.TestCase):
|
|||||||
finally:
|
finally:
|
||||||
self.write_config()
|
self.write_config()
|
||||||
|
|
||||||
|
def add_config_key(self, key, value):
|
||||||
|
self.config_changed = True
|
||||||
|
self.user_defined_config[key] = value
|
||||||
|
self.write_config()
|
||||||
|
|
||||||
def delete_provider_network(self, net_name):
|
def delete_provider_network(self, net_name):
|
||||||
del self.user_defined_config['cidr_networks'][net_name]
|
del self.user_defined_config['cidr_networks'][net_name]
|
||||||
self.write_config()
|
self.write_config()
|
||||||
@ -442,6 +448,10 @@ class TestConfigCheckBase(unittest.TestCase):
|
|||||||
user_defined_config[group][hostname]['ip'] = ip
|
user_defined_config[group][hostname]['ip'] = ip
|
||||||
self.write_config()
|
self.write_config()
|
||||||
|
|
||||||
|
def add_host(self, group, host_name, ip):
|
||||||
|
self.user_defined_config[group][host_name] = {'ip': ip}
|
||||||
|
self.write_config()
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
if self.config_changed:
|
if self.config_changed:
|
||||||
self.restore_config()
|
self.restore_config()
|
||||||
@ -1054,5 +1064,27 @@ class TestNetworkEntry(unittest.TestCase):
|
|||||||
self.assertEqual(entry['interface'], 'eth1')
|
self.assertEqual(entry['interface'], 'eth1')
|
||||||
|
|
||||||
|
|
||||||
|
class TestLxcHosts(TestConfigCheckBase):
|
||||||
|
|
||||||
|
def test_lxc_hosts_group_present(self):
|
||||||
|
inventory = get_inventory()
|
||||||
|
self.assertIn('lxc_hosts', inventory)
|
||||||
|
|
||||||
|
def test_lxc_hosts_only_inserted_once(self):
|
||||||
|
inventory = get_inventory()
|
||||||
|
self.assertEqual(1, len(inventory['lxc_hosts']['hosts']))
|
||||||
|
|
||||||
|
def test_lxc_hosts_members(self):
|
||||||
|
self.add_host('shared-infra_hosts', 'aio2', '172.29.236.101')
|
||||||
|
inventory = get_inventory()
|
||||||
|
self.assertIn('aio2', inventory['lxc_hosts']['hosts'])
|
||||||
|
self.assertIn('aio1', inventory['lxc_hosts']['hosts'])
|
||||||
|
|
||||||
|
def test_lxc_hosts_in_config_raises_error(self):
|
||||||
|
self.add_config_key('lxc_hosts', {})
|
||||||
|
with self.assertRaises(di.LxcHostsDefined):
|
||||||
|
get_inventory()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
Loading…
Reference in New Issue
Block a user