diff --git a/tripleo_common/constants.py b/tripleo_common/constants.py index 0d38548c6..d172c9f6b 100644 --- a/tripleo_common/constants.py +++ b/tripleo_common/constants.py @@ -202,6 +202,8 @@ TRIPLEO_NETWORK_CONFIG_RESOURCE = 'NetworkConfig' HOST_NETWORK = 'ctlplane' +DEFAULT_VLAN_ID = "1" + # The key is different in RoleConfig than in RoleData, so we need both so they # are correctly found. EXTERNAL_TASKS = ['external_deploy_tasks', 'external_deploy_steps_tasks'] diff --git a/tripleo_common/inventory.py b/tripleo_common/inventory.py index 97c2333f2..bb2e8c38e 100644 --- a/tripleo_common/inventory.py +++ b/tripleo_common/inventory.py @@ -16,6 +16,7 @@ # under the License. from collections import OrderedDict +import copy import logging import os import sys @@ -26,6 +27,7 @@ from heatclient.exc import HTTPNotFound import openstack from tripleo_common import exception +import tripleo_common.constants as constants HOST_NETWORK = 'ctlplane' DEFAULT_DOMAIN = 'localdomain.' @@ -93,10 +95,11 @@ class NeutronData(object): A data object with for inventory generation enriched neutron data. """ - def __init__(self, networks, subnets, ports): + def __init__(self, networks, subnets, ports, host_network=None): self.networks = networks self.subnets = subnets self.ports = ports + self.host_network = host_network or HOST_NETWORK self.networks_by_id = self._networks_by_id() self.subnets_by_id = self._subnets_by_id() self.ports_by_role_and_host = self._ports_by_role_and_host() @@ -110,6 +113,15 @@ class NeutronData(object): key, value = tag.rsplit('=') except ValueError: continue + + # Make booleans type bool + value = True if value in {'True', 'true', True} else value + value = False if value in {'False', 'false', False} else value + + # Convert network index value to integer + if key == 'tripleo_net_idx': + value = int(value) + tag_dict.update({key: value}) return tag_dict @@ -124,10 +136,33 @@ class NeutronData(object): # neutron is useless as a inventory source in this case. if not mandatory_tags.issubset(tags): raise exception.MissingMandatoryNeutronResourceTag() + hostname = tags['tripleo_hostname'] - dns_domain = self.networks_by_id[port.network_id]['dns_domain'] - net_name = self.networks_by_id[port.network_id]['name'] - ip_address = port.fixed_ips[0].get('ip_address') + network_id = port.network_id + network = self.networks_by_id[network_id] + fixed_ips = port.fixed_ips[0] + subnet_id = fixed_ips.get('subnet_id') + subnet = self.subnets_by_id[subnet_id] + + # "TripleO" cidr is the number of bits in the network mask + cidr = subnet['cidr'].split('/')[1] + dns_domain = network['dns_domain'] + dns_nameservers = subnet['dns_nameservers'] + mtu = network['mtu'] + net_name = network['name'] + ip_address = fixed_ips.get('ip_address') + gateway_ip = subnet['gateway_ip'] + # Need deepcopy here so that adding default entry does not end + # up in the subnet object and leak to other nodes with a different + # default route network. + host_routes = copy.deepcopy(subnet['host_routes']) + # If this is the default route network, add a default route using + # gateway_ip to the host_routes unless it's already present + if tags.get('tripleo_default_route'): + host_routes.append({'default': True, 'nexthop': gateway_ip}) + + vlan_id = subnet['tags'].get('tripleo_vlan_id', + constants.DEFAULT_VLAN_ID) role_name = tags['tripleo_role'] role = ports_by_role_and_host.setdefault(role_name, {}) @@ -136,24 +171,44 @@ class NeutronData(object): {'name': port.name, 'hostname': hostname, 'dns_domain': dns_domain, - 'network_id': port.network_id, + 'network_id': network_id, 'network_name': net_name, 'fixed_ips': port.fixed_ips, + 'subnet_id': subnet_id, 'ip_address': ip_address, - 'tags': self._tags_to_dict(port.tags)} + 'mtu': mtu, + 'cidr': cidr, + 'gateway_ip': gateway_ip, + 'dns_nameservers': dns_nameservers, + 'host_routes': host_routes, + 'vlan_id': vlan_id, + 'tags': tags} ) return ports_by_role_and_host def _networks_by_id(self): + mandatory_tags = {'tripleo_network_name'} networks_by_id = {} for net in self.networks: + tags = self._tags_to_dict(net.tags) + # In case of missing required tags, raise an error. + # neutron is useless as a inventory source in this case. + if (net.name != self.host_network and + not mandatory_tags.issubset(tags)): + raise exception.MissingMandatoryNeutronResourceTag() + + if net.name != self.host_network: + name_upper = tags['tripleo_network_name'] + else: + name_upper = self.host_network networks_by_id.update( {net.id: {'name': net.name, + 'name_upper': name_upper, 'subnet_ids': net.subnet_ids, 'mtu': net.mtu, 'dns_domain': net.dns_domain, - 'tags': self._tags_to_dict(net.tags)} + 'tags': tags} } ) @@ -428,7 +483,8 @@ class TripleoInventory(object): return data - def _add_host_from_neutron_data(self, host, ports, role_networks): + def _add_host_from_neutron_data(self, host, ports, role_networks, + role_vars): for port in ports: net_name = port['network_name'] @@ -436,6 +492,14 @@ class TripleoInventory(object): if net_name not in role_networks: role_networks.append(net_name) + # Append to role_vars if not already present + net_config_keys = {'cidr', 'dns_nameservers', 'gateway_ip', + 'host_routes', 'vlan_id'} + for key in net_config_keys: + var = '{}_{}'.format(net_name, key) + if var not in role_vars: + role_vars.setdefault(var, port[key]) + # Add variable for hostname on network host.setdefault('{}_hostname'.format(net_name), '.'.join( [port['hostname'], port['dns_domain']])) @@ -459,9 +523,21 @@ class TripleoInventory(object): def _inventory_from_neutron_data(self, ret, children, dynamic): if not self.neutron_data: return + ports_by_role_and_host = self.neutron_data.ports_by_role_and_host + networks_by_id = self.neutron_data.networks_by_id - for role_name, ports_by_host in ( - self.neutron_data.ports_by_role_and_host.items()): + netname_by_idx = { + net['tags'].get('tripleo_net_idx'): + net['tags'].get('tripleo_network_name') + for _, net in networks_by_id.items() + if net['name'] != self.host_network} + networks_all = [netname_by_idx[idx] for idx in sorted(netname_by_idx)] + networks_lower = {net['name_upper']: net['name'] + for _, net in networks_by_id.items()} + networks_upper = {net['name']: net['name_upper'] + for _, net in networks_by_id.items()} + + for role_name, ports_by_host in ports_by_role_and_host.items(): role = ret.setdefault(role_name, {}) hosts = role.setdefault('hosts', {}) role_vars = role.setdefault('vars', {}) @@ -471,9 +547,24 @@ class TripleoInventory(object): role_networks = role_vars.setdefault('tripleo_role_networks', []) for hostname, ports in ports_by_host.items(): host = hosts.setdefault(hostname, {}) - self._add_host_from_neutron_data(host, ports, role_networks) + self._add_host_from_neutron_data(host, ports, role_networks, + role_vars) + + # The nic config templates use ctlplane_subnet_cidr, not + # ctlplane_cidr. Handle the special case. + role_vars.setdefault(self.host_network + '_subnet_cidr', + role_vars[self.host_network + '_cidr']) + role_vars.setdefault('tripleo_role_networks', + sorted(role_networks)) + role_vars.setdefault( + 'role_networks', + [networks_upper[net] for net in role_networks]) + role_vars.setdefault('networks_all', networks_all) + role_vars.setdefault('networks_lower', networks_lower) + + for _, net in networks_by_id.items(): + role_vars.setdefault(net['name'] + '_mtu', net['mtu']) - role_vars['tripleo_role_networks'] = sorted(role_networks) children.add(role_name) self.hostvars.update(hosts) diff --git a/tripleo_common/tests/fake_neutron/fakes.py b/tripleo_common/tests/fake_neutron/fakes.py index 4b56a1c53..e4cce4c05 100644 --- a/tripleo_common/tests/fake_neutron/fakes.py +++ b/tripleo_common/tests/fake_neutron/fakes.py @@ -28,9 +28,11 @@ internal_api_network = stubs.FakeNeutronNetwork( name='internal_api', id='internal_api_network_id', mtu=1500, - dns_domain='inernalapi.example.com', + dns_domain='internalapi.example.com', subnet_ids=['internal_api_subnet_id'], - tags=['tripleo_vip=true', 'tripleo_network_name=InternalApi'], + tags=['tripleo_net_idx=0', + 'tripleo_vip=true', + 'tripleo_network_name=InternalApi'], ) ctlplane_subnet = stubs.FakeNeutronSubnet( @@ -69,7 +71,8 @@ controller0_ports = [ tags=['tripleo_hostname=c-0', 'tripleo_network_name=ctlplane', 'tripleo_role=Controller', - 'tripleo_stack=overcloud'], + 'tripleo_stack=overcloud', + 'tripleo_default_route=True'], ), stubs.FakeNeutronPort(name='c-0-internal_api', id='controller_0_internal_api_id', @@ -79,7 +82,8 @@ controller0_ports = [ tags=['tripleo_hostname=c-0', 'tripleo_network_name=InternalApi', 'tripleo_role=Controller', - 'tripleo_stack=overcloud'], + 'tripleo_stack=overcloud', + 'tripleo_default_route=False'], ), ] @@ -92,7 +96,8 @@ controller1_ports = [ tags=['tripleo_hostname=c-1', 'tripleo_network_name=ctlplane', 'tripleo_role=Controller', - 'tripleo_stack=overcloud'], + 'tripleo_stack=overcloud', + 'tripleo_default_route=True'], ), stubs.FakeNeutronPort(name='c-1-internal_api', id='controller_1_internal_api_id', @@ -102,7 +107,8 @@ controller1_ports = [ tags=['tripleo_hostname=c-1', 'tripleo_network_name=InternalApi', 'tripleo_role=Controller', - 'tripleo_stack=overcloud'], + 'tripleo_stack=overcloud', + 'tripleo_default_route=False'], ), ] @@ -115,7 +121,8 @@ controller2_ports = [ tags=['tripleo_hostname=c-2', 'tripleo_network_name=ctlplane', 'tripleo_role=Controller', - 'tripleo_stack=overcloud'], + 'tripleo_stack=overcloud', + 'tripleo_default_route=True'], ), stubs.FakeNeutronPort(name='c-2-internal_api', id='controller_2_internal_api_id', @@ -125,7 +132,8 @@ controller2_ports = [ tags=['tripleo_hostname=c-2', 'tripleo_network_name=InternalApi', 'tripleo_role=Controller', - 'tripleo_stack=overcloud'], + 'tripleo_stack=overcloud', + 'tripleo_default_route=False'], ), ] @@ -138,7 +146,8 @@ compute_0_ports = [ tags=['tripleo_hostname=cp-0', 'tripleo_network_name=ctlplane', 'tripleo_role=Compute', - 'tripleo_stack=overcloud'], + 'tripleo_stack=overcloud', + 'tripleo_default_route=True'], ), stubs.FakeNeutronPort(name='cp-0-internal_api', id='compute_0_internal_api_id', @@ -148,7 +157,8 @@ compute_0_ports = [ tags=['tripleo_hostname=cp-0', 'tripleo_network_name=InternalApi', 'tripleo_role=Compute', - 'tripleo_stack=overcloud'], + 'tripleo_stack=overcloud', + 'tripleo_default_route=False'], ), ] @@ -162,6 +172,7 @@ custom_0_ports = [ tags=['tripleo_hostname=cs-0', 'tripleo_network_name=ctlplane', 'tripleo_role=CustomRole', - 'tripleo_stack=overcloud'], + 'tripleo_stack=overcloud', + 'tripleo_default_route=True'], ), ] diff --git a/tripleo_common/tests/test_inventory.py b/tripleo_common/tests/test_inventory.py index a4644ae4c..077cf27c7 100644 --- a/tripleo_common/tests/test_inventory.py +++ b/tripleo_common/tests/test_inventory.py @@ -750,7 +750,8 @@ class TestInventory(base.TestCase): 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) + self.inventory._add_host_from_neutron_data(hosts, ports, role_networks, + role_vars) self.assertEqual(OrderedDict([ ('Compute', {'hosts': { @@ -758,9 +759,21 @@ class TestInventory(base.TestCase): 'canonical_hostname': 'cp-0.example.com.', 'ctlplane_hostname': 'cp-0.ctlplane.example.com.', 'ctlplane_ip': '192.0.2.20', - 'internal_api_hostname': 'cp-0.inernalapi.example.com', + '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) @@ -786,16 +799,35 @@ class TestInventory(base.TestCase): 'canonical_hostname': 'c-0.example.com.', 'ctlplane_hostname': 'c-0.ctlplane.example.com.', 'ctlplane_ip': '192.0.2.10', - 'internal_api_hostname': 'c-0.inernalapi.example.com', + '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.inernalapi.example.com', + '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'] @@ -807,9 +839,28 @@ class TestInventory(base.TestCase): 'canonical_hostname': 'cp-0.example.com.', 'ctlplane_hostname': 'cp-0.ctlplane.example.com.', 'ctlplane_ip': '192.0.2.20', - 'internal_api_hostname': 'cp-0.inernalapi.example.com', + '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'] @@ -834,6 +885,25 @@ class TestInventory(base.TestCase): ('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'] @@ -841,6 +911,25 @@ class TestInventory(base.TestCase): ('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'] @@ -936,7 +1025,7 @@ class TestInventory(base.TestCase): 'ctlplane_hostname': 'c-0.ctlplane.example.com.', 'ctlplane_ip': '192.0.2.10', 'deploy_server_id': 'a', - 'internal_api_hostname': 'c-0.inernalapi.example.com', + 'internal_api_hostname': 'c-0.internalapi.example.com', 'internal_api_ip': '198.51.100.140'}, 'c-1': { 'ansible_host': '192.0.2.11', @@ -944,7 +1033,7 @@ class TestInventory(base.TestCase): 'ctlplane_hostname': 'c-1.ctlplane.example.com.', 'ctlplane_ip': '192.0.2.11', 'deploy_server_id': 'b', - 'internal_api_hostname': 'c-1.inernalapi.example.com', + 'internal_api_hostname': 'c-1.internalapi.example.com', 'internal_api_ip': '198.51.100.141'}, 'c-2': { 'ansible_host': '192.0.2.12', @@ -952,11 +1041,29 @@ class TestInventory(base.TestCase): 'ctlplane_hostname': 'c-2.ctlplane.example.com.', 'ctlplane_ip': '192.0.2.12', 'deploy_server_id': 'c', - 'internal_api_hostname': 'c-2.inernalapi.example.com', + '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']} @@ -969,10 +1076,30 @@ class TestInventory(base.TestCase): 'ctlplane_hostname': 'cp-0.ctlplane.example.com.', 'ctlplane_ip': '192.0.2.20', 'deploy_server_id': 'd', - 'internal_api_hostname': 'cp-0.inernalapi.example.com', + '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']} @@ -987,6 +1114,20 @@ class TestInventory(base.TestCase): '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']} @@ -1042,15 +1183,18 @@ class TestNeutronData(base.TestCase): 'dns_domain': 'ctlplane.example.com.', 'mtu': 1500, 'name': 'ctlplane', + 'name_upper': 'ctlplane', 'subnet_ids': ['ctlplane_subnet_id'], 'tags': {}}, 'internal_api_network_id': { - 'dns_domain': 'inernalapi.example.com', + 'dns_domain': 'internalapi.example.com', 'mtu': 1500, 'name': 'internal_api', + 'name_upper': 'InternalApi', 'subnet_ids': ['internal_api_subnet_id'], - 'tags': {'tripleo_network_name': 'InternalApi', - 'tripleo_vip': 'true'} + 'tags': {'tripleo_net_idx': 0, + 'tripleo_network_name': 'InternalApi', + 'tripleo_vip': True} }, }, self.neutron_data.networks_by_id) @@ -1079,87 +1223,146 @@ class TestNeutronData(base.TestCase): }, self.neutron_data.subnets_by_id) def test__ports_by_role_and_host(self): - self.assertEqual({ - 'Controller': { - 'c-0': [ - {'dns_domain': 'ctlplane.example.com.', - 'fixed_ips': [{'ip_address': '192.0.2.10', - 'subnet_id': 'ctlplane_subnet_id'}], - 'hostname': 'c-0', - 'ip_address': '192.0.2.10', - 'name': 'c-0-ctlplane', - 'network_id': 'ctlplane_network_id', - 'network_name': 'ctlplane', - 'tags': {'tripleo_hostname': 'c-0', - 'tripleo_network_name': 'ctlplane', - 'tripleo_role': 'Controller', - 'tripleo_stack': 'overcloud'}}, - {'dns_domain': 'inernalapi.example.com', - 'fixed_ips': [{'ip_address': '198.51.100.140', - 'subnet_id': 'internal_api_subnet_id'}], - 'hostname': 'c-0', - 'ip_address': '198.51.100.140', - 'name': 'c-0-internal_api', - 'network_id': 'internal_api_network_id', - 'network_name': 'internal_api', - 'tags': {'tripleo_hostname': 'c-0', - 'tripleo_network_name': 'InternalApi', - 'tripleo_role': 'Controller', - 'tripleo_stack': 'overcloud'}}, - ], - 'c-1': [ - {'dns_domain': 'ctlplane.example.com.', - 'fixed_ips': [{'ip_address': '192.0.2.11', - 'subnet_id': 'ctlplane_subnet_id'}], - 'hostname': 'c-1', - 'ip_address': '192.0.2.11', - 'name': 'c-1-ctlplane', - 'network_id': 'ctlplane_network_id', - 'network_name': 'ctlplane', - 'tags': {'tripleo_hostname': 'c-1', - 'tripleo_network_name': 'ctlplane', - 'tripleo_role': 'Controller', - 'tripleo_stack': 'overcloud'}}, - {'dns_domain': 'inernalapi.example.com', - 'fixed_ips': [{'ip_address': '198.51.100.141', - 'subnet_id': 'internal_api_subnet_id'}], - 'hostname': 'c-1', - 'ip_address': '198.51.100.141', - 'name': 'c-1-internal_api', - 'network_id': 'internal_api_network_id', - 'network_name': 'internal_api', - 'tags': {'tripleo_hostname': 'c-1', - 'tripleo_network_name': 'InternalApi', - 'tripleo_role': 'Controller', - 'tripleo_stack': 'overcloud'}}, - ] - }, - 'Compute': { - 'cp-0': [ - {'dns_domain': 'ctlplane.example.com.', - 'fixed_ips': [{'ip_address': '192.0.2.20', - 'subnet_id': 'ctlplane_subnet_id'}], - 'hostname': 'cp-0', - 'ip_address': '192.0.2.20', - 'name': 'cp-0-ctlplane', - 'network_id': 'ctlplane_network_id', - 'network_name': 'ctlplane', - 'tags': {'tripleo_hostname': 'cp-0', - 'tripleo_network_name': 'ctlplane', - 'tripleo_role': 'Compute', - 'tripleo_stack': 'overcloud'}}, - {'dns_domain': 'inernalapi.example.com', - 'fixed_ips': [{'ip_address': '198.51.100.150', - 'subnet_id': 'internal_api_subnet_id'}], - 'hostname': 'cp-0', - 'ip_address': '198.51.100.150', - 'name': 'cp-0-internal_api', - 'network_id': 'internal_api_network_id', - 'network_name': 'internal_api', - 'tags': {'tripleo_hostname': 'cp-0', - 'tripleo_network_name': 'InternalApi', - 'tripleo_role': 'Compute', - 'tripleo_stack': 'overcloud'}}, - ] - }, - }, self.neutron_data.ports_by_role_and_host) + 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_hostname': 'c-0', + '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_hostname': 'c-0', + '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_hostname': 'c-1', + '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_hostname': 'c-1', + '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_hostname': 'cp-0', + '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_hostname': 'cp-0', + '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)