1428 lines
60 KiB
Python
1428 lines
60 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
# 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.
|
|
|
|
from collections import OrderedDict
|
|
import fixtures
|
|
import os
|
|
import sys
|
|
from unittest import mock
|
|
|
|
import yaml
|
|
|
|
from heatclient.exc import HTTPNotFound
|
|
|
|
from tripleo_common.inventory import NeutronData
|
|
from tripleo_common.inventory import StackOutputs
|
|
from tripleo_common.inventory import TripleoInventory
|
|
from tripleo_common.tests import base
|
|
from tripleo_common.tests.fake_neutron import fakes as neutron_fakes
|
|
|
|
|
|
MOCK_ENABLED_SERVICES = {
|
|
"ObjectStorage": [
|
|
"kernel",
|
|
"swift_storage",
|
|
"tripleo_packages"
|
|
],
|
|
"Controller": [
|
|
"kernel",
|
|
"keystone",
|
|
"tripleo_packages"
|
|
],
|
|
"Compute": [
|
|
"nova_compute",
|
|
"kernel",
|
|
"tripleo_packages",
|
|
"ceph_client"
|
|
],
|
|
"CephStorage": [
|
|
"kernel",
|
|
"tripleo_packages"
|
|
],
|
|
"BlockStorage": [
|
|
"cinder_volume",
|
|
"kernel",
|
|
"tripleo_packages"
|
|
]
|
|
}
|
|
|
|
|
|
class TestInventory(base.TestCase):
|
|
def setUp(self):
|
|
super(TestInventory, self).setUp()
|
|
self.outputs_data = {'outputs': [
|
|
{
|
|
'output_key': 'EnabledServices',
|
|
'output_value': {
|
|
'Controller': ['sa', 'sb'],
|
|
'Compute': ['sd', 'se', 'ceph_client'],
|
|
'CustomRole': ['sg', 'sh']}
|
|
},
|
|
{
|
|
'output_key': 'KeystoneURL',
|
|
'output_value': 'xyz://keystone'
|
|
},
|
|
{
|
|
'output_key': 'ServerIdData',
|
|
'output_value': {
|
|
'server_ids': {
|
|
'Controller': ['a', 'b', 'c'],
|
|
'Compute': ['d'],
|
|
'CustomRole': ['e']
|
|
},
|
|
'bootstrap_server_id': 'a'
|
|
}
|
|
},
|
|
{
|
|
'output_key': 'RoleNetHostnameMap',
|
|
'output_value': {
|
|
'Controller': {
|
|
'ctlplane': [
|
|
'c-0.ctlplane.localdomain',
|
|
'c-1.ctlplane.localdomain',
|
|
'c-2.ctlplane.localdomain'],
|
|
'internal_api': [
|
|
'c-0.internal_api.localdomain',
|
|
'c-1.internal_api.localdomain',
|
|
'c-2.internal_api.localdomain']
|
|
},
|
|
'Compute': {
|
|
'ctlplane': ['cp-0.ctlplane.localdomain']
|
|
},
|
|
'CustomRole': {
|
|
'ctlplane': ['cs-0.ctlplane.localdomain']
|
|
}
|
|
}
|
|
},
|
|
{
|
|
'output_key': 'RoleNetIpMap',
|
|
'output_value': {
|
|
'Controller': {
|
|
'ctlplane': [
|
|
'x.x.x.1',
|
|
'x.x.x.2',
|
|
'x.x.x.3'
|
|
],
|
|
'internal_api': [
|
|
'x.x.x.4',
|
|
'x.x.x.5',
|
|
'x.x.x.6'
|
|
]
|
|
},
|
|
'Compute': {
|
|
'ctlplane': ['y.y.y.1']
|
|
},
|
|
'CustomRole': {
|
|
'ctlplane': ['z.z.z.1']
|
|
}
|
|
}
|
|
},
|
|
{
|
|
'output_key': 'VipMap',
|
|
'output_value': {
|
|
'ctlplane': 'x.x.x.4',
|
|
'redis': 'x.x.x.6'
|
|
}
|
|
},
|
|
{
|
|
'output_key': 'RoleData',
|
|
'output_value': {
|
|
'Controller': {'config_settings': 'foo1'},
|
|
'Compute': {'config_settings': 'foo2'},
|
|
'CustomRole': {'config_settings': 'foo3'}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
self.plan_name = 'overcloud'
|
|
self.hclient = mock.MagicMock()
|
|
self.hclient.stacks.environment.return_value = {
|
|
'parameter_defaults': {
|
|
'AdminPassword': 'theadminpw',
|
|
'ContainerCli': 'podman'
|
|
}
|
|
}
|
|
self.mock_stack = mock.MagicMock()
|
|
self.mock_stack.outputs = self.outputs_data['outputs']
|
|
self.hclient.stacks.get.return_value = self.mock_stack
|
|
self.outputs = StackOutputs(self.mock_stack)
|
|
self.connection = mock.MagicMock()
|
|
patcher = mock.patch('openstack.connect',
|
|
return_value=self.connection)
|
|
patcher.start()
|
|
self.inventory = TripleoInventory(
|
|
cloud_name='undercloud',
|
|
hclient=self.hclient,
|
|
plan_name=self.plan_name,
|
|
ansible_ssh_user='heat-admin')
|
|
self.inventory.stack_outputs = self.outputs
|
|
self.addCleanup(patcher.stop)
|
|
|
|
def test_get_roles_by_service(self):
|
|
services = TripleoInventory.get_roles_by_service(MOCK_ENABLED_SERVICES)
|
|
expected = {
|
|
'kernel': [
|
|
'BlockStorage',
|
|
'CephStorage',
|
|
'Compute',
|
|
'Controller',
|
|
'ObjectStorage'
|
|
],
|
|
'swift_storage': ['ObjectStorage'],
|
|
'tripleo_packages': [
|
|
'BlockStorage',
|
|
'CephStorage',
|
|
'Compute',
|
|
'Controller',
|
|
'ObjectStorage'
|
|
],
|
|
'keystone': ['Controller'],
|
|
'nova_compute': ['Compute'],
|
|
'cinder_volume': ['BlockStorage'],
|
|
'ceph_client': ['Compute'],
|
|
}
|
|
self.assertDictEqual(services, expected)
|
|
|
|
def test_stack_not_found(self):
|
|
self.hclient.stacks.get.side_effect = HTTPNotFound('not found')
|
|
self.assertEqual(None, self.inventory._get_stack())
|
|
|
|
def test_outputs_valid_key_calls_api(self):
|
|
expected = 'xyz://keystone'
|
|
self.hclient.stacks.output_show.return_value = dict(output=dict(
|
|
output_value=expected))
|
|
self.assertEqual(expected, self.outputs['KeystoneURL'])
|
|
# This should also support the get method
|
|
self.assertEqual(expected, self.outputs.get('KeystoneURL'))
|
|
self.assertTrue(self.hclient.called_once_with(
|
|
'overcloud', 'KeystoneURL'))
|
|
|
|
def test_no_ips(self):
|
|
for output in self.outputs_data['outputs']:
|
|
if output['output_key'] == 'RoleNetIpMap':
|
|
output['output_value'] = dict(Controller=dict(ctlplane=[]))
|
|
self.assertRaises(Exception, self.inventory.list)
|
|
|
|
def test_outputs_invalid_key_raises_keyerror(self):
|
|
self.assertRaises(KeyError, lambda: self.outputs['Invalid'])
|
|
|
|
def test_outputs_get_method_returns_default(self):
|
|
default = 'default value'
|
|
self.assertEqual(default, self.outputs.get('Invalid', default))
|
|
|
|
def test_outputs_iterating_returns_list_of_output_keys(self):
|
|
self.assertEqual({
|
|
'EnabledServices',
|
|
'KeystoneURL',
|
|
'ServerIdData',
|
|
'RoleNetHostnameMap',
|
|
'RoleNetIpMap',
|
|
'VipMap',
|
|
'RoleData'
|
|
}, set([o for o in self.outputs]))
|
|
|
|
def test_inventory_list(self):
|
|
self.inventory.undercloud_connection = 'local'
|
|
self._inventory_list(self.inventory)
|
|
|
|
def _inventory_list(self, inventory):
|
|
ansible_ssh_user = 'heat-admin'
|
|
expected = {
|
|
'Compute': {
|
|
'hosts': ['cp-0'],
|
|
'vars': {
|
|
'ansible_ssh_user': ansible_ssh_user,
|
|
'bootstrap_server_id': 'a',
|
|
'serial': 1,
|
|
'tripleo_role_name': 'Compute',
|
|
'tripleo_role_networks': ['ctlplane']
|
|
}
|
|
},
|
|
'Controller': {
|
|
'hosts': ['c-0', 'c-1', 'c-2'],
|
|
'vars': {
|
|
'ansible_ssh_user': ansible_ssh_user,
|
|
'bootstrap_server_id': 'a',
|
|
'serial': 1,
|
|
'tripleo_role_name': 'Controller',
|
|
'tripleo_role_networks': [
|
|
'ctlplane',
|
|
'internal_api'
|
|
]
|
|
}
|
|
},
|
|
'CustomRole': {
|
|
'hosts': ['cs-0'],
|
|
'vars': {
|
|
'ansible_ssh_user': ansible_ssh_user,
|
|
'bootstrap_server_id': 'a',
|
|
'serial': 1,
|
|
'tripleo_role_name': 'CustomRole',
|
|
'tripleo_role_networks': ['ctlplane']
|
|
}
|
|
},
|
|
'overcloud': {
|
|
'children': ['allovercloud']
|
|
},
|
|
'allovercloud': {
|
|
'children': ['Compute', 'Controller', 'CustomRole'],
|
|
'vars': {
|
|
'container_cli': 'podman',
|
|
'ctlplane_vip': 'x.x.x.4',
|
|
'redis_vip': 'x.x.x.6'
|
|
}
|
|
},
|
|
'Undercloud': {
|
|
'hosts': ['undercloud'],
|
|
'vars': {
|
|
'ansible_connection': 'local',
|
|
'ansible_host': 'localhost',
|
|
'ansible_python_interpreter': sys.executable,
|
|
'ansible_remote_tmp': '/tmp/ansible-${USER}',
|
|
'overcloud_keystone_url': 'xyz://keystone',
|
|
'overcloud_admin_password': 'theadminpw',
|
|
'plan': 'overcloud',
|
|
'undercloud_service_list': [
|
|
'tripleo_nova_compute',
|
|
'tripleo_heat_engine',
|
|
'tripleo_ironic_conductor',
|
|
'tripleo_swift_container_server',
|
|
'tripleo_swift_object_server',
|
|
'tripleo_mistral_engine'
|
|
],
|
|
}
|
|
}
|
|
}
|
|
inv_list = inventory.list()
|
|
for k in expected:
|
|
self.assertEqual(expected[k], inv_list[k])
|
|
|
|
def test_inventory_list_undercloud_installer(self):
|
|
outputs_data = {
|
|
'outputs': [
|
|
{'output_key': 'EnabledServices',
|
|
'output_value': {'Undercloud': ['sa', 'sb']}},
|
|
{'output_key': 'KeystoneURL',
|
|
'output_value': 'xyz://keystone'},
|
|
{'output_key': 'ServerIdData',
|
|
'output_value': {'server_ids': {'Undercloud': ['a']},
|
|
'bootstrap_server_id': 'a'}},
|
|
{'output_key': 'RoleNetHostnameMap',
|
|
'output_value': {'Undercloud': {
|
|
'ctlplane': ['uc0.ctlplane.localdomain'],
|
|
'external': ['uc0.external.localdomain'],
|
|
'canonical': ['uc0.lab.example.com']}}},
|
|
{'output_key': 'RoleNetIpMap',
|
|
'output_value': {'Undercloud': {'ctlplane': ['x.x.x.1'],
|
|
'external': ['x.x.x.1']}}},
|
|
{'output_key': 'VipMap',
|
|
'output_value': {'ctlplane': 'x.x.x.4', 'redis': 'x.x.x.6'}},
|
|
{'output_key': 'RoleData',
|
|
'output_value': {'Undercloud': {'config_settings': 'foo1'}}}
|
|
]
|
|
}
|
|
|
|
self.hclient.stacks.environment.return_value = {
|
|
'parameter_defaults': {
|
|
'AdminPassword': 'theadminpw', 'ContainerCli': 'podman'}}
|
|
mock_stack = mock.MagicMock()
|
|
mock_stack.outputs = outputs_data['outputs']
|
|
self.hclient.stacks.get.return_value = mock_stack
|
|
|
|
outputs = StackOutputs(mock_stack)
|
|
inventory = TripleoInventory(
|
|
hclient=self.hclient,
|
|
cloud_name='undercloud',
|
|
plan_name='overcloud',
|
|
ansible_ssh_user='heat-admin')
|
|
inventory.stack_outputs = outputs
|
|
expected = {
|
|
'Undercloud': {
|
|
'hosts': {
|
|
'uc0': {
|
|
'ansible_host': 'x.x.x.1',
|
|
'canonical_hostname': 'uc0.lab.example.com',
|
|
'ctlplane_hostname': 'uc0.ctlplane.localdomain',
|
|
'ctlplane_ip': 'x.x.x.1',
|
|
'deploy_server_id': 'a',
|
|
'external_hostname': 'uc0.external.localdomain',
|
|
'external_ip': 'x.x.x.1'}},
|
|
'vars': {
|
|
'ansible_ssh_user': 'heat-admin',
|
|
'bootstrap_server_id': 'a',
|
|
'serial': 1,
|
|
'tripleo_role_name': 'Undercloud',
|
|
'tripleo_role_networks': ['ctlplane', 'external']}},
|
|
'allovercloud': {
|
|
'children': {'Undercloud': {}},
|
|
'vars': {'container_cli': 'podman',
|
|
'ctlplane_vip': 'x.x.x.4',
|
|
'redis_vip': 'x.x.x.6'}},
|
|
'sb': {'children': {'Undercloud': {}},
|
|
'vars': {'ansible_ssh_user': 'heat-admin'}},
|
|
'sa': {'children': {'Undercloud': {}},
|
|
'vars': {'ansible_ssh_user': 'heat-admin'}}
|
|
}
|
|
inv_list = inventory.list(dynamic=False)
|
|
for k in expected:
|
|
self.assertEqual(expected[k], inv_list[k])
|
|
|
|
def test_inventory_list_undercloud_only(self):
|
|
self.inventory.plan_name = None
|
|
self.inventory.undercloud_connection = 'local'
|
|
expected = {
|
|
'Undercloud': {
|
|
'hosts': ['undercloud'],
|
|
'vars': {
|
|
'ansible_connection': 'local',
|
|
'ansible_host': 'localhost',
|
|
'ansible_python_interpreter': sys.executable,
|
|
'ansible_remote_tmp': '/tmp/ansible-${USER}',
|
|
'undercloud_service_list': [
|
|
'tripleo_nova_compute',
|
|
'tripleo_heat_engine',
|
|
'tripleo_ironic_conductor',
|
|
'tripleo_swift_container_server',
|
|
'tripleo_swift_object_server',
|
|
'tripleo_mistral_engine'
|
|
],
|
|
}
|
|
},
|
|
'_meta': {'hostvars': {}},
|
|
}
|
|
self.assertEqual(expected, self.inventory.list())
|
|
|
|
def test_ansible_ssh_user(self):
|
|
self._try_alternative_args(
|
|
ansible_ssh_user='my-custom-admin', undercloud_connection='ssh')
|
|
|
|
def _try_alternative_args(self, ansible_ssh_user, undercloud_connection):
|
|
key_file = '/var/lib/mistral/.ssh/%s-key' % ansible_ssh_user
|
|
self.inventory = TripleoInventory(
|
|
hclient=self.hclient,
|
|
cloud_name='undercloud',
|
|
plan_name=self.plan_name,
|
|
ansible_ssh_user=ansible_ssh_user,
|
|
undercloud_connection=undercloud_connection,
|
|
undercloud_key_file=key_file,
|
|
ansible_python_interpreter='foo'
|
|
)
|
|
|
|
self.inventory.stack_outputs = self.outputs
|
|
|
|
expected = {
|
|
'Compute': {
|
|
'hosts': ['cp-0'],
|
|
'vars': {
|
|
'ansible_python_interpreter': 'foo',
|
|
'ansible_ssh_user': ansible_ssh_user,
|
|
'bootstrap_server_id': 'a',
|
|
'serial': 1,
|
|
'tripleo_role_name': 'Compute',
|
|
'tripleo_role_networks': ['ctlplane']
|
|
}
|
|
},
|
|
'Controller': {
|
|
'hosts': ['c-0', 'c-1', 'c-2'],
|
|
'vars': {
|
|
'ansible_python_interpreter': 'foo',
|
|
'ansible_ssh_user': ansible_ssh_user,
|
|
'bootstrap_server_id': 'a',
|
|
'serial': 1,
|
|
'tripleo_role_name': 'Controller',
|
|
'tripleo_role_networks': [
|
|
'ctlplane',
|
|
'internal_api'
|
|
]
|
|
}
|
|
},
|
|
'CustomRole': {
|
|
'hosts': ['cs-0'],
|
|
'vars': {
|
|
'ansible_python_interpreter': 'foo',
|
|
'ansible_ssh_user': ansible_ssh_user,
|
|
'bootstrap_server_id': 'a',
|
|
'serial': 1,
|
|
'tripleo_role_name': 'CustomRole',
|
|
'tripleo_role_networks': ['ctlplane']
|
|
}
|
|
},
|
|
'overcloud': {
|
|
'children': ['allovercloud']
|
|
},
|
|
'allovercloud': {
|
|
'children': ['Compute', 'Controller', 'CustomRole'],
|
|
'vars': {
|
|
'container_cli': 'podman',
|
|
'ctlplane_vip': 'x.x.x.4',
|
|
'redis_vip': 'x.x.x.6'
|
|
}
|
|
},
|
|
'sa': {
|
|
'children': ['Controller'],
|
|
'vars': {
|
|
'ansible_ssh_user': 'my-custom-admin',
|
|
'ansible_python_interpreter': 'foo'
|
|
}
|
|
},
|
|
'sb': {
|
|
'children': ['Controller'],
|
|
'vars': {
|
|
'ansible_ssh_user': 'my-custom-admin',
|
|
'ansible_python_interpreter': 'foo'
|
|
}
|
|
},
|
|
'sd': {
|
|
'children': ['Compute'],
|
|
'vars': {
|
|
'ansible_ssh_user': 'my-custom-admin',
|
|
'ansible_python_interpreter': 'foo'
|
|
}
|
|
},
|
|
'se': {
|
|
'children': ['Compute'],
|
|
'vars': {
|
|
'ansible_ssh_user': 'my-custom-admin',
|
|
'ansible_python_interpreter': 'foo'
|
|
}
|
|
},
|
|
'ceph_client': {
|
|
'children': ['Compute'],
|
|
'vars': {
|
|
'ansible_ssh_user': 'my-custom-admin',
|
|
'ansible_python_interpreter': 'foo'
|
|
}
|
|
},
|
|
'clients': {
|
|
'children': ['Compute'],
|
|
'vars': {
|
|
'ansible_ssh_user': 'my-custom-admin',
|
|
'ansible_python_interpreter': 'foo'
|
|
}
|
|
},
|
|
'sg': {
|
|
'children': ['CustomRole'],
|
|
'vars': {
|
|
'ansible_ssh_user': 'my-custom-admin',
|
|
'ansible_python_interpreter': 'foo'
|
|
}
|
|
},
|
|
'sh': {
|
|
'children': ['CustomRole'],
|
|
'vars': {
|
|
'ansible_ssh_user': 'my-custom-admin',
|
|
'ansible_python_interpreter': 'foo'
|
|
}
|
|
},
|
|
'Undercloud': {
|
|
'hosts': ['undercloud'],
|
|
'vars': {
|
|
'ansible_connection': 'ssh',
|
|
'ansible_ssh_private_key_file': key_file,
|
|
'ansible_ssh_user': 'my-custom-admin',
|
|
'ansible_host': 'localhost',
|
|
'ansible_python_interpreter': 'foo',
|
|
'ansible_remote_tmp': '/tmp/ansible-${USER}',
|
|
'overcloud_keystone_url': 'xyz://keystone',
|
|
'overcloud_admin_password': 'theadminpw',
|
|
'plan': 'overcloud',
|
|
'undercloud_service_list': [
|
|
'tripleo_nova_compute',
|
|
'tripleo_heat_engine',
|
|
'tripleo_ironic_conductor',
|
|
'tripleo_swift_container_server',
|
|
'tripleo_swift_object_server',
|
|
'tripleo_mistral_engine'],
|
|
}
|
|
}
|
|
}
|
|
|
|
inv_list = self.inventory.list()
|
|
for k in expected:
|
|
self.assertEqual(expected[k], inv_list[k])
|
|
|
|
def test_inventory_write_static(self):
|
|
self.inventory.undercloud_connection = 'local'
|
|
self._inventory_write_static()
|
|
|
|
def test_inventory_write_static_extra_vars(self):
|
|
self.inventory.undercloud_connection = 'local'
|
|
extra_vars = {'Undercloud': {'anextravar': 123}}
|
|
self._inventory_write_static(extra_vars=extra_vars)
|
|
|
|
def _inventory_write_static(self, extra_vars=None):
|
|
tmp_dir = self.useFixture(fixtures.TempDir()).path
|
|
inv_path = os.path.join(tmp_dir, "inventory.yaml")
|
|
self.inventory.write_static_inventory(inv_path, extra_vars)
|
|
ansible_ssh_user = 'heat-admin'
|
|
expected = {
|
|
'Undercloud': {
|
|
'hosts': {'undercloud': {}},
|
|
'vars': {
|
|
'ansible_connection': 'local',
|
|
'ansible_host': 'localhost',
|
|
'ansible_python_interpreter':
|
|
sys.executable,
|
|
'ansible_remote_tmp':
|
|
'/tmp/ansible-${USER}',
|
|
'overcloud_admin_password': 'theadminpw',
|
|
'overcloud_keystone_url': 'xyz://keystone',
|
|
'plan': 'overcloud',
|
|
'undercloud_service_list': [
|
|
'tripleo_nova_compute',
|
|
'tripleo_heat_engine',
|
|
'tripleo_ironic_conductor',
|
|
'tripleo_swift_container_server',
|
|
'tripleo_swift_object_server',
|
|
'tripleo_mistral_engine'],
|
|
}
|
|
},
|
|
'Controller': {
|
|
'hosts': {
|
|
'c-0': {
|
|
'ansible_host': 'x.x.x.1',
|
|
'ctlplane_ip': 'x.x.x.1',
|
|
'deploy_server_id': 'a',
|
|
'ctlplane_hostname': 'c-0.ctlplane.localdomain',
|
|
'internal_api_hostname':
|
|
'c-0.internal_api.localdomain',
|
|
'internal_api_ip': 'x.x.x.4'
|
|
},
|
|
'c-1': {
|
|
'ansible_host': 'x.x.x.2',
|
|
'ctlplane_ip': 'x.x.x.2',
|
|
'deploy_server_id': 'b',
|
|
'ctlplane_hostname': 'c-1.ctlplane.localdomain',
|
|
'internal_api_hostname':
|
|
'c-1.internal_api.localdomain',
|
|
'internal_api_ip': 'x.x.x.5'
|
|
},
|
|
'c-2': {
|
|
'ansible_host': 'x.x.x.3',
|
|
'ctlplane_ip': 'x.x.x.3',
|
|
'deploy_server_id': 'c',
|
|
'ctlplane_hostname': 'c-2.ctlplane.localdomain',
|
|
'internal_api_hostname':
|
|
'c-2.internal_api.localdomain',
|
|
'internal_api_ip': 'x.x.x.6'
|
|
}
|
|
},
|
|
'vars': {
|
|
'ansible_ssh_user': ansible_ssh_user,
|
|
'bootstrap_server_id': 'a',
|
|
'serial': 1,
|
|
'tripleo_role_name': 'Controller',
|
|
'tripleo_role_networks': [
|
|
'ctlplane',
|
|
'internal_api'
|
|
]
|
|
}
|
|
},
|
|
'Compute': {
|
|
'hosts': {
|
|
'cp-0': {
|
|
'ansible_host': 'y.y.y.1',
|
|
'ctlplane_ip': 'y.y.y.1',
|
|
'deploy_server_id': 'd',
|
|
'ctlplane_hostname': 'cp-0.ctlplane.localdomain'
|
|
}
|
|
},
|
|
'vars': {
|
|
'ansible_ssh_user': ansible_ssh_user,
|
|
'bootstrap_server_id': 'a',
|
|
'serial': 1,
|
|
'tripleo_role_name': 'Compute',
|
|
'tripleo_role_networks': ['ctlplane']
|
|
}
|
|
},
|
|
'CustomRole': {
|
|
'hosts': {
|
|
'cs-0': {
|
|
'ansible_host': 'z.z.z.1',
|
|
'ctlplane_ip': 'z.z.z.1',
|
|
'deploy_server_id': 'e',
|
|
'ctlplane_hostname': 'cs-0.ctlplane.localdomain'
|
|
}
|
|
},
|
|
'vars': {
|
|
'ansible_ssh_user': ansible_ssh_user,
|
|
'bootstrap_server_id': 'a',
|
|
'serial': 1,
|
|
'tripleo_role_name': 'CustomRole',
|
|
'tripleo_role_networks': ['ctlplane']
|
|
}
|
|
},
|
|
'overcloud': {
|
|
'children': {'allovercloud': {}}
|
|
},
|
|
'allovercloud': {
|
|
'children': {
|
|
'Compute': {},
|
|
'Controller': {},
|
|
'CustomRole': {}
|
|
},
|
|
'vars': {
|
|
'container_cli': 'podman',
|
|
'ctlplane_vip': 'x.x.x.4',
|
|
'redis_vip': 'x.x.x.6'
|
|
}
|
|
},
|
|
'sa': {
|
|
'children': {'Controller': {}},
|
|
'vars': {'ansible_ssh_user': 'heat-admin'}
|
|
},
|
|
'sb': {
|
|
'children': {'Controller': {}},
|
|
'vars': {'ansible_ssh_user': 'heat-admin'}
|
|
},
|
|
'sd': {
|
|
'children': {'Compute': {}},
|
|
'vars': {'ansible_ssh_user': 'heat-admin'}
|
|
},
|
|
'se': {
|
|
'children': {'Compute': {}},
|
|
'vars': {'ansible_ssh_user': 'heat-admin'}
|
|
},
|
|
'ceph_client': {
|
|
'children': {'Compute': {}},
|
|
'vars': {'ansible_ssh_user': 'heat-admin'}
|
|
},
|
|
'clients': {
|
|
'children': {'Compute': {}},
|
|
'vars': {'ansible_ssh_user': 'heat-admin'}
|
|
},
|
|
'sg': {
|
|
'children': {'CustomRole': {}},
|
|
'vars': {'ansible_ssh_user': 'heat-admin'}
|
|
},
|
|
'sh': {
|
|
'children': {'CustomRole': {}},
|
|
'vars': {'ansible_ssh_user': 'heat-admin'}
|
|
},
|
|
}
|
|
if extra_vars:
|
|
expected['Undercloud']['vars']['anextravar'] = 123
|
|
|
|
with open(inv_path, 'r') as f:
|
|
loaded_inv = yaml.safe_load(f)
|
|
self.assertEqual(expected, loaded_inv)
|
|
|
|
def test__add_host_from_neutron_data(self):
|
|
neutron_data = NeutronData(networks=neutron_fakes.fake_networks,
|
|
subnets=neutron_fakes.fake_subnets,
|
|
ports=neutron_fakes.compute_0_ports)
|
|
ret = OrderedDict()
|
|
role = ret.setdefault('Compute', {})
|
|
role_vars = role.setdefault('vars', {})
|
|
role_networks = role_vars.setdefault('tripleo_role_networks', [])
|
|
hosts = role.setdefault('hosts', {})
|
|
ports = neutron_data.ports_by_role_and_host['Compute']['cp-0']
|
|
self.inventory._add_host_from_neutron_data(hosts, ports, role_networks,
|
|
role_vars)
|
|
self.assertEqual(OrderedDict([
|
|
('Compute',
|
|
{'hosts': {
|
|
'ansible_host': '192.0.2.20',
|
|
'canonical_hostname': 'cp-0.example.com',
|
|
'ctlplane_hostname': 'cp-0.ctlplane.example.com',
|
|
'ctlplane_ip': '192.0.2.20',
|
|
'internal_api_hostname': 'cp-0.internalapi.example.com',
|
|
'internal_api_ip': '198.51.100.150'},
|
|
'vars': {
|
|
'ctlplane_cidr': '24',
|
|
'ctlplane_dns_nameservers': ['192.0.2.253',
|
|
'192.0.2.254'],
|
|
'ctlplane_gateway_ip': '192.0.2.1',
|
|
'ctlplane_host_routes': [{'default': True,
|
|
'nexthop': '192.0.2.1'}],
|
|
'ctlplane_vlan_id': '1',
|
|
'internal_api_cidr': '25',
|
|
'internal_api_dns_nameservers': [],
|
|
'internal_api_gateway_ip': '198.51.100.129',
|
|
'internal_api_host_routes': [],
|
|
'internal_api_vlan_id': '20',
|
|
'tripleo_role_networks': ['ctlplane', 'internal_api']
|
|
}})
|
|
]), ret)
|
|
|
|
def test__inventory_from_neutron_data(self):
|
|
ret = OrderedDict()
|
|
children = set()
|
|
fake_ports = (neutron_fakes.controller0_ports +
|
|
neutron_fakes.controller1_ports +
|
|
neutron_fakes.compute_0_ports)
|
|
self.inventory.neutron_data = NeutronData(
|
|
networks=neutron_fakes.fake_networks,
|
|
subnets=neutron_fakes.fake_subnets,
|
|
ports=fake_ports)
|
|
|
|
self.inventory._inventory_from_neutron_data(ret, children, False)
|
|
self.assertEqual({'Compute', 'Controller'}, children)
|
|
self.assertEqual(OrderedDict([
|
|
('Controller',
|
|
{'hosts': {
|
|
'c-0': {
|
|
'ansible_host': '192.0.2.10',
|
|
'canonical_hostname': 'c-0.example.com',
|
|
'ctlplane_hostname': 'c-0.ctlplane.example.com',
|
|
'ctlplane_ip': '192.0.2.10',
|
|
'internal_api_hostname': 'c-0.internalapi.example.com',
|
|
'internal_api_ip': '198.51.100.140'},
|
|
'c-1': {
|
|
'ansible_host': '192.0.2.11',
|
|
'canonical_hostname': 'c-1.example.com',
|
|
'ctlplane_hostname': 'c-1.ctlplane.example.com',
|
|
'ctlplane_ip': '192.0.2.11',
|
|
'internal_api_hostname': 'c-1.internalapi.example.com',
|
|
'internal_api_ip': '198.51.100.141'}},
|
|
'vars': {'ansible_ssh_user': 'heat-admin',
|
|
'ctlplane_cidr': '24',
|
|
'ctlplane_dns_nameservers': ['192.0.2.253',
|
|
'192.0.2.254'],
|
|
'ctlplane_gateway_ip': '192.0.2.1',
|
|
'ctlplane_host_routes': [{'default': True,
|
|
'nexthop': '192.0.2.1'}],
|
|
'ctlplane_mtu': 1500,
|
|
'ctlplane_subnet_cidr': '24',
|
|
'ctlplane_vlan_id': '1',
|
|
'internal_api_cidr': '25',
|
|
'internal_api_dns_nameservers': [],
|
|
'internal_api_gateway_ip': '198.51.100.129',
|
|
'internal_api_host_routes': [],
|
|
'internal_api_mtu': 1500,
|
|
'internal_api_vlan_id': '20',
|
|
'networks_all': ['InternalApi'],
|
|
'networks_lower': {'InternalApi': 'internal_api',
|
|
'ctlplane': 'ctlplane'},
|
|
'role_networks': ['ctlplane', 'InternalApi'],
|
|
'serial': 1,
|
|
'tripleo_role_name': 'Controller',
|
|
'tripleo_role_networks': ['ctlplane', 'internal_api']
|
|
}}),
|
|
('Compute',
|
|
{'hosts': {
|
|
'cp-0': {
|
|
'ansible_host': '192.0.2.20',
|
|
'canonical_hostname': 'cp-0.example.com',
|
|
'ctlplane_hostname': 'cp-0.ctlplane.example.com',
|
|
'ctlplane_ip': '192.0.2.20',
|
|
'internal_api_hostname': 'cp-0.internalapi.example.com',
|
|
'internal_api_ip': '198.51.100.150'}},
|
|
'vars': {'ansible_ssh_user': 'heat-admin',
|
|
'ctlplane_cidr': '24',
|
|
'ctlplane_dns_nameservers': ['192.0.2.253',
|
|
'192.0.2.254'],
|
|
'ctlplane_gateway_ip': '192.0.2.1',
|
|
'ctlplane_host_routes': [{'default': True,
|
|
'nexthop': '192.0.2.1'}],
|
|
'ctlplane_mtu': 1500,
|
|
'ctlplane_subnet_cidr': '24',
|
|
'ctlplane_vlan_id': '1',
|
|
'internal_api_cidr': '25',
|
|
'internal_api_dns_nameservers': [],
|
|
'internal_api_gateway_ip': '198.51.100.129',
|
|
'internal_api_host_routes': [],
|
|
'internal_api_mtu': 1500,
|
|
'internal_api_vlan_id': '20',
|
|
'networks_all': ['InternalApi'],
|
|
'networks_lower': {'InternalApi': 'internal_api',
|
|
'ctlplane': 'ctlplane'},
|
|
'role_networks': ['ctlplane', 'InternalApi'],
|
|
'serial': 1,
|
|
'tripleo_role_name': 'Compute',
|
|
'tripleo_role_networks': ['ctlplane', 'internal_api']
|
|
}}),
|
|
('allovercloud', {'children': {'Compute': {}, 'Controller': {}}})
|
|
]), ret)
|
|
|
|
def test__inventory_from_neutron_data_dynamic(self):
|
|
ret = OrderedDict()
|
|
children = set()
|
|
fake_ports = (neutron_fakes.controller0_ports +
|
|
neutron_fakes.controller1_ports +
|
|
neutron_fakes.compute_0_ports)
|
|
self.inventory.neutron_data = NeutronData(
|
|
networks=neutron_fakes.fake_networks,
|
|
subnets=neutron_fakes.fake_subnets,
|
|
ports=fake_ports)
|
|
|
|
self.inventory._inventory_from_neutron_data(ret, children, True)
|
|
self.assertEqual({'Compute', 'Controller'}, children)
|
|
self.assertEqual(OrderedDict([
|
|
('Controller', {
|
|
'hosts': ['c-0', 'c-1'],
|
|
'vars': {'ansible_ssh_user': 'heat-admin',
|
|
'ctlplane_cidr': '24',
|
|
'ctlplane_dns_nameservers': ['192.0.2.253',
|
|
'192.0.2.254'],
|
|
'ctlplane_gateway_ip': '192.0.2.1',
|
|
'ctlplane_host_routes': [{'default': True,
|
|
'nexthop': '192.0.2.1'}],
|
|
'ctlplane_mtu': 1500,
|
|
'ctlplane_vlan_id': '1',
|
|
'internal_api_cidr': '25',
|
|
'internal_api_dns_nameservers': [],
|
|
'internal_api_gateway_ip': '198.51.100.129',
|
|
'internal_api_host_routes': [],
|
|
'internal_api_mtu': 1500,
|
|
'ctlplane_subnet_cidr': '24',
|
|
'internal_api_vlan_id': '20',
|
|
'networks_all': ['InternalApi'],
|
|
'networks_lower': {'InternalApi': 'internal_api',
|
|
'ctlplane': 'ctlplane'},
|
|
'role_networks': ['ctlplane', 'InternalApi'],
|
|
'serial': 1,
|
|
'tripleo_role_name': 'Controller',
|
|
'tripleo_role_networks': ['ctlplane', 'internal_api']
|
|
}}),
|
|
('Compute', {
|
|
'hosts': ['cp-0'],
|
|
'vars': {'ansible_ssh_user': 'heat-admin',
|
|
'ctlplane_cidr': '24',
|
|
'ctlplane_dns_nameservers': ['192.0.2.253',
|
|
'192.0.2.254'],
|
|
'ctlplane_gateway_ip': '192.0.2.1',
|
|
'ctlplane_host_routes': [{'default': True,
|
|
'nexthop': '192.0.2.1'}],
|
|
'ctlplane_mtu': 1500,
|
|
'ctlplane_vlan_id': '1',
|
|
'internal_api_cidr': '25',
|
|
'internal_api_dns_nameservers': [],
|
|
'internal_api_gateway_ip': '198.51.100.129',
|
|
'internal_api_host_routes': [],
|
|
'internal_api_mtu': 1500,
|
|
'ctlplane_subnet_cidr': '24',
|
|
'internal_api_vlan_id': '20',
|
|
'networks_all': ['InternalApi'],
|
|
'networks_lower': {'InternalApi': 'internal_api',
|
|
'ctlplane': 'ctlplane'},
|
|
'role_networks': ['ctlplane', 'InternalApi'],
|
|
'serial': 1,
|
|
'tripleo_role_name': 'Compute',
|
|
'tripleo_role_networks': ['ctlplane', 'internal_api']
|
|
}}),
|
|
('allovercloud', {'children': ['Compute', 'Controller']})]
|
|
), ret)
|
|
|
|
@mock.patch.object(TripleoInventory, '_get_neutron_data', autospec=True)
|
|
def test_inventory_list_with_neutron_and_heat(self, mock_get_neutron_data):
|
|
fake_ports = (neutron_fakes.controller0_ports +
|
|
neutron_fakes.controller1_ports +
|
|
neutron_fakes.controller2_ports +
|
|
neutron_fakes.compute_0_ports +
|
|
neutron_fakes.custom_0_ports)
|
|
mock_get_neutron_data.return_value = NeutronData(
|
|
networks=neutron_fakes.fake_networks,
|
|
subnets=neutron_fakes.fake_subnets,
|
|
ports=fake_ports)
|
|
inv_list = self.inventory.list(dynamic=False)
|
|
c_0 = inv_list['Controller']['hosts']['c-0']
|
|
c_1 = inv_list['Controller']['hosts']['c-1']
|
|
c_2 = inv_list['Controller']['hosts']['c-2']
|
|
cp_0 = inv_list['Compute']['hosts']['cp-0']
|
|
cs_0 = inv_list['CustomRole']['hosts']['cs-0']
|
|
|
|
# The setdefault pattern should always put the value discovered first
|
|
# in the inventory, neutron source run's prior to heat stack source.
|
|
# Assert IP addresses from neutron fake are used in the
|
|
# inventory, not the heat stack IPs.
|
|
|
|
# Controller
|
|
self.assertNotEqual(
|
|
c_0['ctlplane_ip'],
|
|
self.outputs['RoleNetIpMap']['Controller']['ctlplane'][0])
|
|
self.assertNotEqual(
|
|
c_0['ansible_host'],
|
|
self.outputs['RoleNetIpMap']['Controller']['ctlplane'][0])
|
|
self.assertNotEqual(
|
|
c_1['ctlplane_ip'],
|
|
self.outputs['RoleNetIpMap']['Controller']['ctlplane'][1])
|
|
self.assertNotEqual(
|
|
c_1['ansible_host'],
|
|
self.outputs['RoleNetIpMap']['Controller']['ctlplane'][1])
|
|
self.assertNotEqual(
|
|
c_2['ctlplane_ip'],
|
|
self.outputs['RoleNetIpMap']['Controller']['ctlplane'][2])
|
|
self.assertNotEqual(
|
|
c_2['ansible_host'],
|
|
self.outputs['RoleNetIpMap']['Controller']['ctlplane'][2])
|
|
# Compute
|
|
self.assertNotEqual(
|
|
cp_0['ctlplane_ip'],
|
|
self.outputs['RoleNetIpMap']['Compute']['ctlplane'][0])
|
|
self.assertNotEqual(
|
|
cp_0['ansible_host'],
|
|
self.outputs['RoleNetIpMap']['Compute']['ctlplane'][0])
|
|
# CustomRole
|
|
self.assertNotEqual(
|
|
cs_0['ctlplane_ip'],
|
|
self.outputs['RoleNetIpMap']['CustomRole']['ctlplane'][0])
|
|
self.assertNotEqual(
|
|
cs_0['ansible_host'],
|
|
self.outputs['RoleNetIpMap']['CustomRole']['ctlplane'][0])
|
|
|
|
# IP's and hostnames are from neutron while deploy_server_id and
|
|
# bootstrap_server_id, serial etc are from heat.
|
|
expected = {
|
|
'Undercloud': {
|
|
'hosts': {'undercloud': {}},
|
|
'vars': {'ansible_connection': 'local',
|
|
'ansible_host': 'localhost',
|
|
'ansible_python_interpreter': sys.executable,
|
|
'ansible_remote_tmp': '/tmp/ansible-${USER}',
|
|
'overcloud_admin_password': 'theadminpw',
|
|
'overcloud_keystone_url': 'xyz://keystone',
|
|
'plan': 'overcloud',
|
|
'undercloud_service_list': [
|
|
'tripleo_nova_compute',
|
|
'tripleo_heat_engine',
|
|
'tripleo_ironic_conductor',
|
|
'tripleo_swift_container_server',
|
|
'tripleo_swift_object_server',
|
|
'tripleo_mistral_engine']}},
|
|
'Controller': {
|
|
'hosts': {
|
|
'c-0': {
|
|
'ansible_host': '192.0.2.10',
|
|
'canonical_hostname': 'c-0.example.com',
|
|
'ctlplane_hostname': 'c-0.ctlplane.example.com',
|
|
'ctlplane_ip': '192.0.2.10',
|
|
'deploy_server_id': 'a',
|
|
'internal_api_hostname': 'c-0.internalapi.example.com',
|
|
'internal_api_ip': '198.51.100.140'},
|
|
'c-1': {
|
|
'ansible_host': '192.0.2.11',
|
|
'canonical_hostname': 'c-1.example.com',
|
|
'ctlplane_hostname': 'c-1.ctlplane.example.com',
|
|
'ctlplane_ip': '192.0.2.11',
|
|
'deploy_server_id': 'b',
|
|
'internal_api_hostname': 'c-1.internalapi.example.com',
|
|
'internal_api_ip': '198.51.100.141'},
|
|
'c-2': {
|
|
'ansible_host': '192.0.2.12',
|
|
'canonical_hostname': 'c-2.example.com',
|
|
'ctlplane_hostname': 'c-2.ctlplane.example.com',
|
|
'ctlplane_ip': '192.0.2.12',
|
|
'deploy_server_id': 'c',
|
|
'internal_api_hostname': 'c-2.internalapi.example.com',
|
|
'internal_api_ip': '198.51.100.142'}},
|
|
'vars': {
|
|
'ansible_ssh_user': 'heat-admin',
|
|
'bootstrap_server_id': 'a',
|
|
'ctlplane_cidr': '24',
|
|
'ctlplane_dns_nameservers': ['192.0.2.253', '192.0.2.254'],
|
|
'ctlplane_gateway_ip': '192.0.2.1',
|
|
'ctlplane_host_routes': [{'default': True,
|
|
'nexthop': '192.0.2.1'}],
|
|
'ctlplane_mtu': 1500,
|
|
'ctlplane_subnet_cidr': '24',
|
|
'ctlplane_vlan_id': '1',
|
|
'internal_api_cidr': '25',
|
|
'internal_api_dns_nameservers': [],
|
|
'internal_api_gateway_ip': '198.51.100.129',
|
|
'internal_api_host_routes': [],
|
|
'internal_api_mtu': 1500,
|
|
'internal_api_vlan_id': '20',
|
|
'networks_all': ['InternalApi'],
|
|
'networks_lower': {'InternalApi': 'internal_api',
|
|
'ctlplane': 'ctlplane'},
|
|
'role_networks': ['ctlplane', 'InternalApi'],
|
|
'serial': 1,
|
|
'tripleo_role_name': 'Controller',
|
|
'tripleo_role_networks': ['ctlplane', 'internal_api']}
|
|
},
|
|
'Compute': {
|
|
'hosts': {
|
|
'cp-0': {
|
|
'ansible_host': '192.0.2.20',
|
|
'canonical_hostname': 'cp-0.example.com',
|
|
'ctlplane_hostname': 'cp-0.ctlplane.example.com',
|
|
'ctlplane_ip': '192.0.2.20',
|
|
'deploy_server_id': 'd',
|
|
'internal_api_hostname':
|
|
'cp-0.internalapi.example.com',
|
|
'internal_api_ip': '198.51.100.150'}},
|
|
'vars': {'ansible_ssh_user': 'heat-admin',
|
|
'bootstrap_server_id': 'a',
|
|
'ctlplane_cidr': '24',
|
|
'ctlplane_dns_nameservers': ['192.0.2.253',
|
|
'192.0.2.254'],
|
|
'ctlplane_gateway_ip': '192.0.2.1',
|
|
'ctlplane_host_routes': [{'default': True,
|
|
'nexthop': '192.0.2.1'}],
|
|
'ctlplane_mtu': 1500,
|
|
'ctlplane_subnet_cidr': '24',
|
|
'ctlplane_vlan_id': '1',
|
|
'internal_api_cidr': '25',
|
|
'internal_api_dns_nameservers': [],
|
|
'internal_api_gateway_ip': '198.51.100.129',
|
|
'internal_api_host_routes': [],
|
|
'internal_api_mtu': 1500,
|
|
'internal_api_vlan_id': '20',
|
|
'networks_all': ['InternalApi'],
|
|
'networks_lower': {'InternalApi': 'internal_api',
|
|
'ctlplane': 'ctlplane'},
|
|
'role_networks': ['ctlplane', 'InternalApi'],
|
|
'serial': 1,
|
|
'tripleo_role_name': 'Compute',
|
|
'tripleo_role_networks': ['ctlplane', 'internal_api']}
|
|
},
|
|
'CustomRole': {
|
|
'hosts': {
|
|
'cs-0': {
|
|
'ansible_host': '192.0.2.200',
|
|
'canonical_hostname': 'cs-0.example.com',
|
|
'ctlplane_hostname': 'cs-0.ctlplane.example.com',
|
|
'ctlplane_ip': '192.0.2.200',
|
|
'deploy_server_id': 'e'}},
|
|
'vars': {'ansible_ssh_user': 'heat-admin',
|
|
'bootstrap_server_id': 'a',
|
|
'ctlplane_cidr': '24',
|
|
'ctlplane_dns_nameservers': ['192.0.2.253',
|
|
'192.0.2.254'],
|
|
'ctlplane_gateway_ip': '192.0.2.1',
|
|
'ctlplane_host_routes': [{'default': True,
|
|
'nexthop': '192.0.2.1'}],
|
|
'ctlplane_mtu': 1500,
|
|
'ctlplane_subnet_cidr': '24',
|
|
'ctlplane_vlan_id': '1',
|
|
'internal_api_mtu': 1500,
|
|
'networks_all': ['InternalApi'],
|
|
'networks_lower': {'InternalApi': 'internal_api',
|
|
'ctlplane': 'ctlplane'},
|
|
'role_networks': ['ctlplane'],
|
|
'serial': 1,
|
|
'tripleo_role_name': 'CustomRole',
|
|
'tripleo_role_networks': ['ctlplane']}
|
|
},
|
|
'allovercloud': {
|
|
'children': {'Compute': {},
|
|
'Controller': {},
|
|
'CustomRole': {}},
|
|
'vars': {'container_cli': 'podman',
|
|
'ctlplane_vip': 'x.x.x.4',
|
|
'redis_vip': 'x.x.x.6'}
|
|
},
|
|
'overcloud': {'children': {'allovercloud': {}}},
|
|
'sa': {'children': {'Controller': {}},
|
|
'vars': {'ansible_ssh_user': 'heat-admin'}},
|
|
'se': {'children': {'Compute': {}},
|
|
'vars': {'ansible_ssh_user': 'heat-admin'}},
|
|
'sd': {'children': {'Compute': {}},
|
|
'vars': {'ansible_ssh_user': 'heat-admin'}},
|
|
'sb': {'children': {'Controller': {}},
|
|
'vars': {'ansible_ssh_user': 'heat-admin'}},
|
|
'sg': {'children': {'CustomRole': {}},
|
|
'vars': {'ansible_ssh_user': 'heat-admin'}},
|
|
'ceph_client': {'children': {'Compute': {}},
|
|
'vars': {'ansible_ssh_user': 'heat-admin'}},
|
|
'sh': {'children': {'CustomRole': {}},
|
|
'vars': {'ansible_ssh_user': 'heat-admin'}},
|
|
'clients': {'children': {'Compute': {}},
|
|
'vars': {'ansible_ssh_user': 'heat-admin'}},
|
|
}
|
|
for k in expected:
|
|
self.assertEqual(expected[k], inv_list[k])
|
|
|
|
def test__extend_inventory(self):
|
|
dynamic = False
|
|
existing_inventory = OrderedDict()
|
|
existing_inventory.update({
|
|
'RoleA': {
|
|
'hosts': {
|
|
'host0': {
|
|
'existing': 'existing_value'
|
|
}
|
|
},
|
|
'vars': {
|
|
'existing': 'existing_value'
|
|
},
|
|
}
|
|
})
|
|
extend_data = {
|
|
'RoleA': {
|
|
'hosts': {
|
|
'host0': {
|
|
'new': 'new_value',
|
|
'existing': 'not_overwritten',
|
|
}
|
|
},
|
|
'vars': {
|
|
'new': 'new_var_is_added',
|
|
'existing': 'not_overwritten',
|
|
},
|
|
}
|
|
}
|
|
expected_inventory = OrderedDict([(
|
|
'RoleA', {
|
|
'hosts': {
|
|
'host0': {
|
|
'existing': 'existing_value',
|
|
'new': 'new_value'
|
|
}
|
|
},
|
|
'vars': {
|
|
'existing': 'existing_value',
|
|
'new': 'new_var_is_added'
|
|
}
|
|
}
|
|
)])
|
|
|
|
self.inventory._extend_inventory(existing_inventory, dynamic,
|
|
data=extend_data)
|
|
self.assertEqual(expected_inventory, existing_inventory)
|
|
|
|
def test__extend_inventory_dynamic(self):
|
|
dynamic = True
|
|
existing_inventory = OrderedDict()
|
|
existing_inventory.update({
|
|
'RoleA': {
|
|
'hosts': {
|
|
'host0': {
|
|
'existing': 'existing_value'
|
|
}
|
|
},
|
|
'vars': {
|
|
'existing': 'existing_value'
|
|
},
|
|
}
|
|
})
|
|
extend_data = {
|
|
'RoleA': {
|
|
'hosts': {
|
|
'host0': {
|
|
'new': 'new_value',
|
|
'existing': 'not_overwritten',
|
|
}
|
|
},
|
|
'vars': {
|
|
'new': 'new_var_is_added',
|
|
'existing': 'not_overwritten',
|
|
},
|
|
}
|
|
}
|
|
expected_inventory = OrderedDict([(
|
|
'RoleA', {
|
|
'hosts': ['host0'],
|
|
'vars':
|
|
{'existing': 'existing_value',
|
|
'new': 'new_var_is_added'}})])
|
|
|
|
self.inventory._extend_inventory(existing_inventory, dynamic,
|
|
data=extend_data)
|
|
self.assertEqual(expected_inventory, existing_inventory)
|
|
self.assertEqual(
|
|
{'host0': {'existing': 'existing_value',
|
|
'new': 'new_value'}}, self.inventory.hostvars)
|
|
|
|
|
|
class TestNeutronData(base.TestCase):
|
|
def setUp(self):
|
|
super(TestNeutronData, self).setUp()
|
|
fake_ports = (neutron_fakes.controller0_ports +
|
|
neutron_fakes.controller1_ports +
|
|
neutron_fakes.compute_0_ports)
|
|
self.neutron_data = NeutronData(networks=neutron_fakes.fake_networks,
|
|
subnets=neutron_fakes.fake_subnets,
|
|
ports=fake_ports)
|
|
|
|
def test__tags_to_dict(self):
|
|
tags = ['tripleo_foo=foo', 'tripleo_bar=bar', 'other_tag']
|
|
self.assertEqual({'tripleo_foo': 'foo', 'tripleo_bar': 'bar'},
|
|
NeutronData._tags_to_dict(self, tags))
|
|
|
|
def test__networks_by_id(self):
|
|
self.assertEqual({
|
|
'ctlplane_network_id': {
|
|
'dns_domain': 'ctlplane.example.com.',
|
|
'mtu': 1500,
|
|
'name': 'ctlplane',
|
|
'name_upper': 'ctlplane',
|
|
'subnet_ids': ['ctlplane_subnet_id'],
|
|
'tags': {}},
|
|
'internal_api_network_id': {
|
|
'dns_domain': 'internalapi.example.com.',
|
|
'mtu': 1500,
|
|
'name': 'internal_api',
|
|
'name_upper': 'InternalApi',
|
|
'subnet_ids': ['internal_api_subnet_id'],
|
|
'tags': {'tripleo_net_idx': 0,
|
|
'tripleo_network_name': 'InternalApi',
|
|
'tripleo_vip': True}
|
|
},
|
|
}, self.neutron_data.networks_by_id)
|
|
|
|
def test__subnets_by_id(self):
|
|
self.assertEqual({
|
|
'ctlplane_subnet_id': {
|
|
'cidr': '192.0.2.0/24',
|
|
'dns_nameservers': ['192.0.2.253', '192.0.2.254'],
|
|
'gateway_ip': '192.0.2.1',
|
|
'host_routes': [],
|
|
'ip_version': 4,
|
|
'name': 'ctlplane-subnet',
|
|
'network_id': 'ctlplane_network_id',
|
|
'tags': {}
|
|
},
|
|
'internal_api_subnet_id': {
|
|
'cidr': '198.51.100.128/25',
|
|
'dns_nameservers': [],
|
|
'gateway_ip': '198.51.100.129',
|
|
'host_routes': [],
|
|
'ip_version': 4,
|
|
'name': 'internal_api_subnet',
|
|
'network_id': 'internal_api_network_id',
|
|
'tags': {'tripleo_vlan_id': '20'}
|
|
},
|
|
}, self.neutron_data.subnets_by_id)
|
|
|
|
def test__ports_by_role_and_host(self):
|
|
self.assertTrue(
|
|
'Controller' in self.neutron_data.ports_by_role_and_host)
|
|
self.assertTrue(
|
|
'Compute' in self.neutron_data.ports_by_role_and_host)
|
|
ctr_role = self.neutron_data.ports_by_role_and_host['Controller']
|
|
cmp_role = self.neutron_data.ports_by_role_and_host['Compute']
|
|
self.assertTrue('c-0' in ctr_role)
|
|
self.assertTrue('c-1' in ctr_role)
|
|
ctr_0 = ctr_role['c-0']
|
|
ctr_1 = ctr_role['c-1']
|
|
self.assertTrue('cp-0' in cmp_role)
|
|
cmp_0 = cmp_role['cp-0']
|
|
self.assertEqual(
|
|
[{'cidr': '24',
|
|
'dns_domain': 'ctlplane.example.com',
|
|
'dns_nameservers': ['192.0.2.253', '192.0.2.254'],
|
|
'fixed_ips': [{'ip_address': '192.0.2.10',
|
|
'subnet_id': 'ctlplane_subnet_id'}],
|
|
'gateway_ip': '192.0.2.1',
|
|
'host_routes': [{'default': True, 'nexthop': '192.0.2.1'}],
|
|
'hostname': 'c-0',
|
|
'ip_address': '192.0.2.10',
|
|
'mtu': 1500,
|
|
'name': 'c-0-ctlplane',
|
|
'network_id': 'ctlplane_network_id',
|
|
'network_name': 'ctlplane',
|
|
'subnet_id': 'ctlplane_subnet_id',
|
|
'tags': {'tripleo_default_route': True,
|
|
'tripleo_network_name': 'ctlplane',
|
|
'tripleo_role': 'Controller',
|
|
'tripleo_stack': 'overcloud'},
|
|
'vlan_id': '1'},
|
|
{'cidr': '25',
|
|
'dns_domain': 'internalapi.example.com',
|
|
'dns_nameservers': [],
|
|
'fixed_ips': [{'ip_address': '198.51.100.140',
|
|
'subnet_id': 'internal_api_subnet_id'}],
|
|
'gateway_ip': '198.51.100.129',
|
|
'host_routes': [],
|
|
'hostname': 'c-0',
|
|
'ip_address': '198.51.100.140',
|
|
'mtu': 1500,
|
|
'name': 'c-0-internal_api',
|
|
'network_id': 'internal_api_network_id',
|
|
'network_name': 'internal_api',
|
|
'subnet_id': 'internal_api_subnet_id',
|
|
'tags': {'tripleo_default_route': False,
|
|
'tripleo_network_name': 'InternalApi',
|
|
'tripleo_role': 'Controller',
|
|
'tripleo_stack': 'overcloud'},
|
|
'vlan_id': '20'}],
|
|
ctr_0
|
|
)
|
|
self.assertEqual(
|
|
[{'cidr': '24',
|
|
'dns_domain': 'ctlplane.example.com',
|
|
'dns_nameservers': ['192.0.2.253', '192.0.2.254'],
|
|
'fixed_ips': [{'ip_address': '192.0.2.11',
|
|
'subnet_id': 'ctlplane_subnet_id'}],
|
|
'gateway_ip': '192.0.2.1',
|
|
'host_routes': [{'default': True, 'nexthop': '192.0.2.1'}],
|
|
'hostname': 'c-1',
|
|
'ip_address': '192.0.2.11',
|
|
'mtu': 1500,
|
|
'name': 'c-1-ctlplane',
|
|
'network_id': 'ctlplane_network_id',
|
|
'network_name': 'ctlplane',
|
|
'subnet_id': 'ctlplane_subnet_id',
|
|
'tags': {'tripleo_default_route': True,
|
|
'tripleo_network_name': 'ctlplane',
|
|
'tripleo_role': 'Controller',
|
|
'tripleo_stack': 'overcloud'},
|
|
'vlan_id': '1'},
|
|
{'cidr': '25',
|
|
'dns_domain': 'internalapi.example.com',
|
|
'dns_nameservers': [],
|
|
'fixed_ips': [{'ip_address': '198.51.100.141',
|
|
'subnet_id': 'internal_api_subnet_id'}],
|
|
'gateway_ip': '198.51.100.129',
|
|
'host_routes': [],
|
|
'hostname': 'c-1',
|
|
'ip_address': '198.51.100.141',
|
|
'mtu': 1500,
|
|
'name': 'c-1-internal_api',
|
|
'network_id': 'internal_api_network_id',
|
|
'network_name': 'internal_api',
|
|
'subnet_id': 'internal_api_subnet_id',
|
|
'tags': {'tripleo_default_route': False,
|
|
'tripleo_network_name': 'InternalApi',
|
|
'tripleo_role': 'Controller',
|
|
'tripleo_stack': 'overcloud'},
|
|
'vlan_id': '20'}],
|
|
ctr_1
|
|
)
|
|
self.assertEqual(
|
|
[{'cidr': '24',
|
|
'dns_domain': 'ctlplane.example.com',
|
|
'dns_nameservers': ['192.0.2.253', '192.0.2.254'],
|
|
'fixed_ips': [{'ip_address': '192.0.2.20',
|
|
'subnet_id': 'ctlplane_subnet_id'}],
|
|
'gateway_ip': '192.0.2.1',
|
|
'host_routes': [{'default': True, 'nexthop': '192.0.2.1'}],
|
|
'hostname': 'cp-0',
|
|
'ip_address': '192.0.2.20',
|
|
'mtu': 1500,
|
|
'name': 'cp-0-ctlplane',
|
|
'network_id': 'ctlplane_network_id',
|
|
'network_name': 'ctlplane',
|
|
'subnet_id': 'ctlplane_subnet_id',
|
|
'tags': {'tripleo_default_route': True,
|
|
'tripleo_network_name': 'ctlplane',
|
|
'tripleo_role': 'Compute',
|
|
'tripleo_stack': 'overcloud'},
|
|
'vlan_id': '1'},
|
|
{'cidr': '25',
|
|
'dns_domain': 'internalapi.example.com',
|
|
'dns_nameservers': [],
|
|
'fixed_ips': [{'ip_address': '198.51.100.150',
|
|
'subnet_id': 'internal_api_subnet_id'}],
|
|
'gateway_ip': '198.51.100.129',
|
|
'host_routes': [],
|
|
'hostname': 'cp-0',
|
|
'ip_address': '198.51.100.150',
|
|
'mtu': 1500,
|
|
'name': 'cp-0-internal_api',
|
|
'network_id': 'internal_api_network_id',
|
|
'network_name': 'internal_api',
|
|
'subnet_id': 'internal_api_subnet_id',
|
|
'tags': {'tripleo_default_route': False,
|
|
'tripleo_network_name': 'InternalApi',
|
|
'tripleo_role': 'Compute',
|
|
'tripleo_stack': 'overcloud'},
|
|
'vlan_id': '20'}],
|
|
cmp_0
|
|
)
|
|
self.assertEqual({'Controller': ctr_role, 'Compute': cmp_role},
|
|
self.neutron_data.ports_by_role_and_host)
|