Merge pull request #50 from hjensas/routed-networks

Routed networks
This commit is contained in:
Ben Nemec 2018-10-18 15:38:46 -05:00 committed by GitHub
commit 0911913371
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 460 additions and 125 deletions

View File

@ -8,8 +8,8 @@ resource_registry:
parameter_defaults:
ControlPlaneSubnetCidr: '24'
ControlPlaneDefaultRoute: 192.0.2.1
EC2MetadataIp: 192.0.2.1
ControlPlaneDefaultRoute: 192.168.24.1
EC2MetadataIp: 192.168.24.1
ExternalNetCidr: 10.0.0.0/24
ExternalAllocationPools: [{"start": "10.0.0.10", "end": "10.0.0.50"}]
ExternalInterfaceDefaultRoute: 10.0.0.1

View File

@ -7,14 +7,14 @@ p3
(dp4
S'route'
p5
V192.0.2.1
V192.168.24.1
p6
sS'mask'
p7
I24
sS'ec2'
p8
V192.0.2.1
V192.168.24.1
p9
ssS'major'
p10

View File

@ -37,7 +37,7 @@ method, which creates most of the resources needed automatically.
::
neutron net-create provision
neutron subnet-create --name provision --no-gateway --disable-dhcp provision 192.0.2.0/24
neutron subnet-create --name provision --no-gateway --disable-dhcp provision 192.168.24.0/24
#. Create "public" network.

View File

@ -1,3 +1,5 @@
.. _env-index:
Sample Environment Index
========================
@ -136,6 +138,8 @@ Disable the Undercloud in a QuintupleO Stack
instance.
.. _env-routed-networks-role:
Base Role Configuration for Routed Networks
-------------------------------------------
@ -145,6 +149,8 @@ Base Role Configuration for Routed Networks
deploying with routed networks.
.. _env-enable-routed-networks:
Enable Routed Networks
----------------------

View File

@ -156,3 +156,161 @@ it has only been successfully tested with OVB on Newton and above.
The port-security environments can be recognized by the presence of
`port-security` somewhere in the filename. Network environments without that
substring are the standard ones that require the noop Neutron firewall driver.
QuintupleO and routed networks
------------------------------
TripleO supports deploying OpenStack with nodes on multiple network segments
which is connected via L3 routing. OVB can set up a full development
environment with routers and DHCP-relay service. This environment is targeted
for TripleO development, however it should be useful for non-TripleO users of
OVB as well.
#. When deploying QuintupleO with routed networks environment files to enable
routed networks must be included, as well as one or more role environment
files. See :ref:`env-enable-routed-networks` and
:ref:`env-routed-networks-role` in the :ref:`env-index` for details.
#. Copy the example env file and edit it to reflect the host environment::
cp environments/base.yaml env.yaml
vi env.yaml
#. Copy the ``routed-networks.yaml`` sample environment file and edit it to
reflect the host environment::
cp environments/routed-networks.yaml env-routed-networks.yaml
vi env-routed-networks.yaml
#. For each desired role, copy the ``routed-networks-role.yaml`` sample
environment file and edit it to reflect the host environment::
cp environments/routed-networks-role.yaml env-leaf1.yaml
vi env-leaf1.yaml
#. Deploy the QuintupleO routed networks environment by running the deploy.py
command. For example::
./bin/deploy.py --env env.yaml \
--quintupleo \
--env environments/all-networks-port-security.yaml \
--env env-routed-networks.yaml \
--role env-leaf1.yaml
#. When generateing the ``nodes.json`` file for TripleO undercloud node import
the environment ``env-routed.yaml`` should be specified. Also to include
physical network attributes of the node ports in ``nodes.json`` specify the
``--physical_network`` option when running ``build-nodes-json``. For
example::
bin/build-nodes-json --physical_network
The following is an example node definition produced when using the
``--physical-network`` options. (Notice that ports are defined with both
``address`` and ``physical_network`` attributes.
::
{
"pm_password": "password",
"name": "baremetal-leaf1-0",
"memory": 8192,
"pm_addr": "10.0.1.13",
"ports": [
{
"physical_network": "provision2",
"address": "fa:16:3e:2f:a1:cf"
}
],
"capabilities": "boot_option:local,profile:leaf1",
"pm_type": "pxe_ipmitool",
"disk": 80,
"arch": "x86_64",
"cpu": 4,
"pm_user": "admin"
}
.. NOTE:: Due to technical debet (backward compatibility) the TripleO
Undercloud uses ``ctlplane`` as the physical network name for the
subnet that is local to the Undercloud itself. Either override
the name of the provision network in the ovb environment by
setting: ``provision_net: ctlplane`` in the
``parameters_defaults`` section or edit the generated nodes.json
file, replacing:
``"physical_network": "<name-used-for-provision_net>"`` with
``"physical_network": "ctlplane"``.
#. For convenience router addresses are made available via the
``network_environment_data`` key in the stack output of the quintupleo heat
stack. To retrieve this data run the ``openstack stack show`` command. For
example::
$ openstack stack show quintupleo -c outputs -f yaml
outputs:
- description: floating ip of the undercloud instance
output_key: undercloud_host_floating_ip
output_value: 38.145.35.98
- description: Network environment data, router addresses etc.
output_key: network_environment_data
output_value:
internal2_router: 172.17.1.204
internal_router_address: 172.17.0.201
provision2_router: 192.168.25.254
provision3_router: 192.168.26.254
provision_router: 192.168.24.254
storage2_router_address: 172.18.1.254
storage_mgmt2_router_address: 172.19.1.254
storage_mgmt_router_address: 172.19.0.254
storage_router_address: 172.18.0.254
tenant2_router_address: 172.16.1.254
tenant_router_address: 172.16.0.254
- description: ip of the undercloud instance on the private network
output_key: undercloud_host_private_ip
output_value: 10.0.1.14
#. Below is an example TripleO Undercloud configuration (``undercloud.conf``)
with routed networks support enabled and the three provisioning networks
defined.
::
[DEFAULT]
enable_routed_networks = true
enable_ui = false
overcloud_domain_name = localdomain
scheduler_max_attempts = 2
undercloud_ntp_servers = pool.ntp.org
undercloud_hostname = undercloud.rdocloud
local_interface = eth1
local_mtu = 1450
local_ip = 192.168.24.1/24
undercloud_public_host = 192.168.24.2
undercloud_admin_host = 192.168.24.3
undercloud_nameservers = 8.8.8.8,8.8.4.4
local_subnet = provision
subnets = provision,provision2,provision3
[provision]
cidr = 192.168.24.0/24
dhcp_start = 192.168.24.10
dhcp_end = 192.168.24.30
gateway = 192.168.24.254
inspection_iprange = 192.168.24.100,192.168.24.120
masquerade = true
[provision2]
cidr = 192.168.25.0/24
dhcp_start = 192.168.25.10
dhcp_end = 192.168.25.30
gateway = 192.168.25.254
inspection_iprange = 192.168.25.100,192.168.25.120
masquerade = true
[provision3]
cidr = 192.168.26.0/24
dhcp_start = 192.168.26.10
dhcp_end = 192.168.26.30
gateway = 192.168.26.254
inspection_iprange = 192.168.26.100,192.168.26.120
masquerade = true

View File

@ -8,8 +8,8 @@ resource_registry:
parameter_defaults:
ControlPlaneSubnetCidr: '24'
ControlPlaneDefaultRoute: 192.0.2.1
EC2MetadataIp: 192.0.2.1
ControlPlaneDefaultRoute: 192.168.24.1
EC2MetadataIp: 192.168.24.1
ExternalNetCidr: 2001:db8:fd00:1000::/64
ExternalAllocationPools: [{"start": "2001:db8:fd00:1000::10", "end": "2001:db8:fd00:1000:ffff:ffff:ffff:fffe"}]
ExternalInterfaceDefaultRoute: 2001:db8:fd00:1000::1

View File

@ -7,14 +7,14 @@ p3
(dp4
S'route'
p5
V192.0.2.1
V192.168.24.1
p6
sS'mask'
p7
I24
sS'ec2'
p8
V192.0.2.1
V192.168.24.1
p9
ssS'major'
p10

View File

@ -8,8 +8,8 @@ resource_registry:
parameter_defaults:
ControlPlaneSubnetCidr: '24'
ControlPlaneDefaultRoute: 192.0.2.1
EC2MetadataIp: 192.0.2.1
ControlPlaneDefaultRoute: 192.168.24.1
EC2MetadataIp: 192.168.24.1
ExternalNetCidr: 10.0.0.0/24
ExternalAllocationPools: [{"start": "10.0.0.10", "end": "10.0.0.50"}]
ExternalInterfaceDefaultRoute: 10.0.0.1

View File

@ -7,14 +7,14 @@ p3
(dp4
S'route'
p5
V192.0.2.1
V192.168.24.1
p6
sS'mask'
p7
I24
sS'ec2'
p8
V192.0.2.1
V192.168.24.1
p9
ssS'major'
p10

View File

@ -45,7 +45,7 @@ def _parse_args():
parser.add_argument('--provision_net',
dest='provision_net',
default='provision',
help='Provisioning network name')
help='DEPRECATED: This parameter is ignored.')
parser.add_argument('--nodes_json',
dest='nodes_json',
default='nodes.json',
@ -82,7 +82,6 @@ def _get_names(args):
if args.env is None:
bmc_base = args.bmc_prefix
baremetal_base = args.baremetal_prefix
provision_net = args.provision_net
# FIXME: This is not necessarily true.
undercloud_name = 'undercloud'
else:
@ -90,12 +89,11 @@ def _get_names(args):
e = yaml.safe_load(f)
bmc_base = _get_from_env(e, 'bmc_prefix')
baremetal_base = _get_from_env(e, 'baremetal_prefix')
provision_net = _get_from_env(e, 'provision_net')
role = e.get('parameter_defaults', {}).get('role')
if role and baremetal_base.endswith('-' + role):
baremetal_base = baremetal_base[:-len(role) - 1]
undercloud_name = e.get('parameter_defaults', {}).get('undercloud_name') # noqa: E501
return bmc_base, baremetal_base, provision_net, undercloud_name
return bmc_base, baremetal_base, undercloud_name
def _get_clients():
@ -116,10 +114,17 @@ def _get_ports(neutron, bmc_base, baremetal_base):
raise RuntimeError('Found different numbers of baremetal and '
'bmc ports. bmc: %s baremetal: %s' % (bmc_ports,
bm_ports))
return bmc_ports, bm_ports
provision_net_map = {}
for port in bm_ports:
provision_net_map.update({
port.get('id'):
neutron.list_subnets(
id=port['fixed_ips'][0]['subnet_id'])['subnets'][0].get(
'name')})
return bmc_ports, bm_ports, provision_net_map
def _build_nodes(nova, glance, bmc_ports, bm_ports, provision_net,
def _build_nodes(nova, glance, bmc_ports, bm_ports, provision_net_map,
baremetal_base, undercloud_name, driver, physical_network):
node_template = {
'pm_type': driver,
@ -136,9 +141,6 @@ def _build_nodes(nova, glance, bmc_ports, bm_ports, provision_net,
}
if physical_network:
node_template.pop('mac')
node_template.update(
{'ports': [{'address': '', 'physical_network': provision_net}]})
nodes = []
bmc_bm_pairs = []
cache = {}
@ -151,9 +153,11 @@ def _build_nodes(nova, glance, bmc_ports, bm_ports, provision_net,
node = dict(node_template)
node['pm_addr'] = bmc_port['fixed_ips'][0]['ip_address']
bmc_bm_pairs.append((node['pm_addr'], baremetal.name))
provision_net = provision_net_map.get(baremetal_port['id'])
mac = baremetal.addresses[provision_net][0]['OS-EXT-IPS-MAC:mac_addr']
if physical_network:
node['ports'][0]['address'] = mac
node.update({'ports': [{'address': mac,
'physical_network': provision_net}]})
else:
node['mac'] = [mac]
if not cache.get(baremetal.flavor['id']):
@ -282,14 +286,15 @@ def _write_pairs(bmc_bm_pairs):
def main():
args = _parse_args()
bmc_base, baremetal_base, provision_net, undercloud_name = _get_names(args)
bmc_base, baremetal_base, undercloud_name = _get_names(args)
nova, neutron, glance = _get_clients()
bmc_ports, bm_ports = _get_ports(neutron, bmc_base, baremetal_base)
bmc_ports, bm_ports, provision_net_map = _get_ports(neutron, bmc_base,
baremetal_base)
(nodes,
bmc_bm_pairs,
extra_nodes,
network_details) = _build_nodes(nova, glance, bmc_ports, bm_ports,
provision_net, baremetal_base,
provision_net_map, baremetal_base,
undercloud_name, args.driver,
args.physical_network)
_write_nodes(nodes, extra_nodes, network_details, args)

View File

@ -113,15 +113,17 @@ def _add_identifier(env_data, name, identifier, default=None):
env_data['parameter_defaults'] = {}
parameter = False
try:
original = env_data['parameters'][name]
value = env_data['parameters'][name]
parameter = True
except KeyError:
original = env_data['parameter_defaults'].get(name)
if original is None:
original = default
if original is None:
value = env_data['parameter_defaults'].get(name)
if value is None:
value = default
if value is None:
raise RuntimeError('No base value found when adding id')
value = '%s-%s' % (original, identifier)
if identifier:
value = '%s-%s' % (value, identifier)
# If it was passed in as a parameter we need to set it in the parameters
# section or it will be overridden by the original value. We can't always
# do that though because some parameters are not exposed at the top-level.
@ -358,7 +360,7 @@ def _process_role(role_file, base_envs, stack_name, args):
'private': role_env['parameter_defaults']['private_net'],
'provision': role_env['parameter_defaults']['provision_net'],
'public': role_env['parameter_defaults']['public_net'],
}
}
role_file = 'env-%s-%s.yaml' % (stack_name, role)
_write_role_file(role_env, role_file)
return role_file, role

View File

@ -70,13 +70,11 @@ class TestBuildNodesJson(testtools.TestCase):
args.env = None
args.bmc_prefix = 'bmc-foo'
args.baremetal_prefix = 'baremetal-foo'
args.provision_net = 'provision-foo'
args.add_undercloud = False
bmc_base, baremetal_base, provision_net, undercloud_name = (
bmc_base, baremetal_base, undercloud_name = (
build_nodes_json._get_names(args))
self.assertEqual('bmc-foo', bmc_base)
self.assertEqual('baremetal-foo', baremetal_base)
self.assertEqual('provision-foo', provision_net)
self.assertEqual('undercloud', undercloud_name)
def test_get_names_no_env_w_undercloud(self):
@ -84,13 +82,11 @@ class TestBuildNodesJson(testtools.TestCase):
args.env = None
args.bmc_prefix = 'bmc-foo'
args.baremetal_prefix = 'baremetal-foo'
args.provision_net = 'provision-foo'
args.add_undercloud = True
bmc_base, baremetal_base, provision_net, undercloud_name = (
bmc_base, baremetal_base, undercloud_name = (
build_nodes_json._get_names(args))
self.assertEqual('bmc-foo', bmc_base)
self.assertEqual('baremetal-foo', baremetal_base)
self.assertEqual('provision-foo', provision_net)
self.assertEqual('undercloud', undercloud_name)
@mock.patch('openstack_virtual_baremetal.build_nodes_json.open',
@ -104,15 +100,13 @@ class TestBuildNodesJson(testtools.TestCase):
'parameters': {
'bmc_prefix': 'bmc-foo',
'baremetal_prefix': 'baremetal-foo',
'provision_net': 'provision-foo'
},
}
mock_load.return_value = mock_env
bmc_base, baremetal_base, provision_net, undercloud_name = (
bmc_base, baremetal_base, undercloud_name = (
build_nodes_json._get_names(args))
self.assertEqual('bmc-foo', bmc_base)
self.assertEqual('baremetal-foo', baremetal_base)
self.assertEqual('provision-foo', provision_net)
self.assertIsNone(undercloud_name)
@mock.patch('openstack_virtual_baremetal.build_nodes_json.open',
@ -126,15 +120,13 @@ class TestBuildNodesJson(testtools.TestCase):
'parameter_defaults': {
'bmc_prefix': 'bmc-foo',
'baremetal_prefix': 'baremetal-foo',
'provision_net': 'provision-foo'
},
}
mock_load.return_value = mock_env
bmc_base, baremetal_base, provision_net, undercloud_name = (
bmc_base, baremetal_base, undercloud_name = (
build_nodes_json._get_names(args))
self.assertEqual('bmc-foo', bmc_base)
self.assertEqual('baremetal-foo', baremetal_base)
self.assertEqual('provision-foo', provision_net)
self.assertIsNone(undercloud_name)
@mock.patch('openstack_virtual_baremetal.build_nodes_json.open',
@ -148,16 +140,14 @@ class TestBuildNodesJson(testtools.TestCase):
'parameter_defaults': {
'bmc_prefix': 'bmc',
'baremetal_prefix': 'baremetal',
'provision_net': 'provision',
'role': 'foo',
},
}
mock_load.return_value = mock_env
bmc_base, baremetal_base, provision_net, undercloud_name = (
bmc_base, baremetal_base, undercloud_name = (
build_nodes_json._get_names(args))
self.assertEqual('bmc', bmc_base)
self.assertEqual('baremetal', baremetal_base)
self.assertEqual('provision', provision_net)
self.assertIsNone(undercloud_name)
@mock.patch('openstack_virtual_baremetal.build_nodes_json.open',
@ -171,16 +161,14 @@ class TestBuildNodesJson(testtools.TestCase):
'parameter_defaults': {
'bmc_prefix': 'bmc-foo',
'baremetal_prefix': 'baremetal-foo-bar',
'provision_net': 'provision-foo',
'role': 'bar',
},
}
mock_load.return_value = mock_env
bmc_base, baremetal_base, provision_net, undercloud_name = (
bmc_base, baremetal_base, undercloud_name = (
build_nodes_json._get_names(args))
self.assertEqual('bmc-foo', bmc_base)
self.assertEqual('baremetal-foo', baremetal_base)
self.assertEqual('provision-foo', provision_net)
self.assertIsNone(undercloud_name)
@mock.patch('os_client_config.make_client')
@ -203,21 +191,42 @@ class TestBuildNodesJson(testtools.TestCase):
def test_get_ports(self):
neutron = mock.Mock()
fake_fixed_ips = [{'subnet_id': 'provision_id'}]
fake_ports = {
'ports': [
{'name': 'random'},
{'name': 'bmc_1'},
{'name': 'bmc_0'},
{'name': 'baremetal_1'},
{'name': 'baremetal_0'},
{'name': 'random',
'id': 'random_id',
'fixed_ips': fake_fixed_ips},
{'name': 'bmc_1',
'id': 'bmc_1_id',
'fixed_ips': fake_fixed_ips},
{'name': 'bmc_0',
'id': 'bmc_0_id',
'fixed_ips': fake_fixed_ips},
{'name': 'baremetal_1',
'id': 'baremetal_1_id',
'fixed_ips': fake_fixed_ips},
{'name': 'baremetal_0',
'id': 'baremetal_0_id',
'fixed_ips': fake_fixed_ips},
]
}
fake_subnets = {
'subnets': [
{'name': 'provision',
'id': 'provision_id'}
]
}
neutron.list_ports.return_value = fake_ports
bmc_ports, bm_ports = build_nodes_json._get_ports(neutron, 'bmc',
'baremetal')
self.assertEqual([{'name': 'bmc_0'}, {'name': 'bmc_1'}], bmc_ports)
self.assertEqual([{'name': 'baremetal_0'}, {'name': 'baremetal_1'}],
neutron.list_subnets.return_value = fake_subnets
bmc_ports, bm_ports, provision_net_map = build_nodes_json._get_ports(
neutron, 'bmc', 'baremetal')
self.assertEqual([fake_ports['ports'][2], fake_ports['ports'][1]],
bmc_ports)
self.assertEqual([fake_ports['ports'][4], fake_ports['ports'][3]],
bm_ports)
self.assertEqual({'baremetal_0_id': 'provision',
'baremetal_1_id': 'provision'}, provision_net_map)
def test_get_ports_mismatch(self):
neutron = mock.Mock()
@ -228,20 +237,38 @@ class TestBuildNodesJson(testtools.TestCase):
def test_get_ports_multiple(self):
neutron = mock.Mock()
fake_fixed_ips = [{'subnet_id': 'provision_id'}]
fake_ports = {
'ports': [
{'name': 'random'},
{'name': 'bmc-foo_0'},
{'name': 'bmc-bar_0'},
{'name': 'baremetal-foo_0'},
{'name': 'baremetal-bar_0'},
{'name': 'random',
'id': 'random_id',
'fixed_ips': fake_fixed_ips},
{'name': 'bmc-foo_0',
'id': 'bmc_foo_0_id',
'fixed_ips': fake_fixed_ips},
{'name': 'bmc-bar_0',
'id': 'bmc_bar_0_id',
'fixed_ips': fake_fixed_ips},
{'name': 'baremetal-foo_0',
'id': 'baremetal_foo_0_id',
'fixed_ips': fake_fixed_ips},
{'name': 'baremetal-bar_0',
'id': 'baremetal_bar_0_id',
'fixed_ips': fake_fixed_ips},
]
}
fake_subnets = {
'subnets': [
{'name': 'provision',
'id': 'provision_id'}
]
}
neutron.list_ports.return_value = fake_ports
bmc_ports, bm_ports = build_nodes_json._get_ports(neutron, 'bmc-foo',
'baremetal-foo')
self.assertEqual([{'name': 'bmc-foo_0'}], bmc_ports)
self.assertEqual([{'name': 'baremetal-foo_0'}], bm_ports)
neutron.list_subnets.return_value = fake_subnets
bmc_ports, bm_ports, provision_net_map = build_nodes_json._get_ports(
neutron, 'bmc-foo', 'baremetal-foo')
self.assertEqual([fake_ports['ports'][1]], bmc_ports)
self.assertEqual([fake_ports['ports'][3]], bm_ports)
def _fake_port(self, device_id, ip, mac):
return {'device_id': device_id,
@ -275,7 +302,11 @@ class TestBuildNodesJson(testtools.TestCase):
bmc_ports = [{'fixed_ips': [{'ip_address': '1.1.1.1'}]},
{'fixed_ips': [{'ip_address': '1.1.1.2'}]}
]
bm_ports = [{'device_id': '1'}, {'device_id': '2'}]
bm_ports = [{'device_id': '1', 'id': 'port_id_server1'},
{'device_id': '2', 'id': 'port_id_server2'}]
provision_net_map = {'port_id_server1': 'provision',
'port_id_server2': 'provision',
'port_id_server3': 'provision', }
physical_network = False
nova = mock.Mock()
servers = [mock.Mock(), mock.Mock(), mock.Mock()]
@ -304,8 +335,8 @@ class TestBuildNodesJson(testtools.TestCase):
bmc_bm_pairs,
extra_nodes,
network_details) = build_nodes_json._build_nodes(
nova, glance, bmc_ports, bm_ports, 'provision', 'bm', 'undercloud',
'pxe_ipmitool', physical_network)
nova, glance, bmc_ports, bm_ports, provision_net_map, 'bm',
'undercloud', 'pxe_ipmitool', physical_network)
expected_nodes = copy.deepcopy(TEST_NODES)
expected_nodes[1]['disk'] = 100
self.assertEqual(expected_nodes, nodes)
@ -323,7 +354,11 @@ class TestBuildNodesJson(testtools.TestCase):
bmc_ports = [{'fixed_ips': [{'ip_address': '1.1.1.1'}]},
{'fixed_ips': [{'ip_address': '1.1.1.2'}]}
]
bm_ports = [{'device_id': '1'}, {'device_id': '2'}]
bm_ports = [{'device_id': '1', 'id': 'port_id_server1'},
{'device_id': '2', 'id': 'port_id_server2'}]
provision_net_map = {'port_id_server1': 'provision',
'port_id_server2': 'provision',
'port_id_server3': 'provision', }
physical_network = False
nova = mock.Mock()
servers = [mock.Mock(), mock.Mock(), mock.Mock()]
@ -352,8 +387,8 @@ class TestBuildNodesJson(testtools.TestCase):
bmc_bm_pairs,
extra_nodes,
network_details) = build_nodes_json._build_nodes(
nova, glance, bmc_ports, bm_ports, 'provision', 'bm', 'undercloud',
'ipmi', physical_network)
nova, glance, bmc_ports, bm_ports, provision_net_map, 'bm',
'undercloud', 'ipmi', physical_network)
expected_nodes = copy.deepcopy(TEST_NODES)
expected_nodes[1]['disk'] = 100
for node in expected_nodes:
@ -372,7 +407,11 @@ class TestBuildNodesJson(testtools.TestCase):
bmc_ports = [{'fixed_ips': [{'ip_address': '1.1.1.1'}]},
{'fixed_ips': [{'ip_address': '1.1.1.2'}]}
]
bm_ports = [{'device_id': '1'}, {'device_id': '2'}]
bm_ports = [{'device_id': '1', 'id': 'port_id_server1'},
{'device_id': '2', 'id': 'port_id_server2'}]
provision_net_map = {'port_id_server1': 'provision',
'port_id_server2': 'provision',
'port_id_server3': 'provision', }
physical_network = False
nova = mock.Mock()
servers = [mock.Mock(), mock.Mock(), mock.Mock()]
@ -388,8 +427,8 @@ class TestBuildNodesJson(testtools.TestCase):
glance.images.get.return_value = mock_image_get
nodes, bmc_bm_pairs, extra_nodes, _ = build_nodes_json._build_nodes(
nova, glance, bmc_ports, bm_ports, 'provision', 'bm-foo', None,
'pxe_ipmitool', physical_network)
nova, glance, bmc_ports, bm_ports, provision_net_map, 'bm-foo',
None, 'pxe_ipmitool', physical_network)
expected_nodes = copy.deepcopy(TEST_NODES)
expected_nodes[0]['name'] = 'bm-foo-control-0'
expected_nodes[0]['capabilities'] = ('boot_option:local,'
@ -495,9 +534,9 @@ class TestBuildNodesJson(testtools.TestCase):
mock_parse_args.return_value = args
bmc_base = mock.Mock()
baremetal_base = mock.Mock()
provision_net = mock.Mock()
provision_net_map = mock.Mock()
undercloud_name = 'undercloud'
mock_get_names.return_value = (bmc_base, baremetal_base, provision_net,
mock_get_names.return_value = (bmc_base, baremetal_base,
undercloud_name)
nova = mock.Mock()
neutron = mock.Mock()
@ -505,7 +544,7 @@ class TestBuildNodesJson(testtools.TestCase):
mock_get_clients.return_value = (nova, neutron, glance)
bmc_ports = mock.Mock()
bm_ports = mock.Mock()
mock_get_ports.return_value = (bmc_ports, bm_ports)
mock_get_ports.return_value = (bmc_ports, bm_ports, provision_net_map)
nodes = mock.Mock()
pairs = mock.Mock()
extra_nodes = mock.Mock()
@ -521,7 +560,7 @@ class TestBuildNodesJson(testtools.TestCase):
mock_get_ports.assert_called_once_with(neutron, bmc_base,
baremetal_base)
mock_build_nodes.assert_called_once_with(nova, glance, bmc_ports,
bm_ports, provision_net,
bm_ports, provision_net_map,
baremetal_base,
undercloud_name,
args.driver,

View File

@ -192,11 +192,11 @@ class TestIdEnv(unittest.TestCase):
# _process_role test data
role_base_data = {
'parameter_defaults': {
'overcloud_storage_mgmt_net': 'storage_mgmt-foo',
'overcloud_internal_net': 'internal-foo',
'overcloud_storage_net': 'storage-foo',
'overcloud_storage_mgmt_net': 'storage_mgmt',
'overcloud_internal_net': 'internal',
'overcloud_storage_net': 'storage',
'overcloud_tenant_net': 'tenant',
'role': 'control',
'overcloud_tenant_net': 'tenant-foo'
},
'parameters': {
'os_user': 'admin',
@ -213,7 +213,6 @@ role_base_data = {
'undercloud_image': 'centos7-base',
'baremetal_image': 'ipxe-boot',
'external_net': 'external',
'private_net': 'private',
'baremetal_prefix': 'baremetal-foo-control',
'undercloud_flavor': 'undercloud-16',
'node_count': 3,
@ -229,6 +228,9 @@ role_base_data = {
role_specific_data = {
'parameter_defaults': {
'role': 'compute',
'public_net': 'public',
'private_net': 'private',
'provision_net': 'provision',
},
'parameters': {
'key_name': 'default',
@ -254,16 +256,13 @@ role_original_data = {
'undercloud_name': 'undercloud',
'baremetal_flavor': 'baremetal',
'os_auth_url': 'http://1.1.1.1:5000/v2.0',
'provision_net': 'provision',
'bmc_image': 'bmc-base',
'os_tenant': 'admin',
'bmc_prefix': 'bmc',
'public_net': 'public',
'undercloud_image': 'centos7-base',
'baremetal_image': 'ipxe-boot',
'external_net': 'external',
'os_password': 'password',
'private_net': 'private',
'undercloud_flavor': 'undercloud-16',
'node_count': 3,
'bmc_flavor': 'bmc'
@ -398,8 +397,16 @@ class TestDeploy(testtools.TestCase):
output['parameters']['bmc_prefix'])
# These should be inherited
self.assertEqual('ipxe-boot', output['parameters']['baremetal_image'])
self.assertEqual('tenant-foo',
self.assertEqual('tenant-' + args.id,
output['parameter_defaults']['overcloud_tenant_net'])
self.assertEqual('internal-' + args.id,
output['parameter_defaults']['overcloud_internal_net']
)
self.assertEqual('storage-' + args.id,
output['parameter_defaults']['overcloud_storage_net'])
self.assertEqual('storage_mgmt-' + args.id,
output['parameter_defaults'][
'overcloud_storage_mgmt_net'])
# This should not be present in a role env, even if set in the file
self.assertNotIn('OS::OVB::BaremetalNetworks',
output['resource_registry'])

View File

@ -8,8 +8,8 @@ resource_registry:
parameter_defaults:
ControlPlaneSubnetCidr: '24'
ControlPlaneDefaultRoute: 192.0.2.1
EC2MetadataIp: 192.0.2.1
ControlPlaneDefaultRoute: 192.168.24.1
EC2MetadataIp: 192.168.24.1
ExternalNetCidr: 10.0.0.0/24
ExternalAllocationPools: [{"start": "10.0.0.10", "end": "10.0.0.50"}]
ExternalInterfaceDefaultRoute: 10.0.0.1

View File

@ -7,14 +7,14 @@ p3
(dp4
S'route'
p5
V192.0.2.1
V192.168.24.1
p6
sS'mask'
p7
I24
sS'ec2'
p8
V192.0.2.1
V192.168.24.1
p9
ssS'major'
p10

View File

@ -8,8 +8,8 @@ resource_registry:
parameter_defaults:
ControlPlaneSubnetCidr: '24'
ControlPlaneDefaultRoute: 192.0.2.1
EC2MetadataIp: 192.0.2.1
ControlPlaneDefaultRoute: 192.168.24.1
EC2MetadataIp: 192.168.24.1
ExternalNetCidr: 2001:db8:fd00:1000::/64
ExternalAllocationPools: [{"start": "2001:db8:fd00:1000::10", "end": "2001:db8:fd00:1000:ffff:ffff:ffff:fffe"}]
ExternalInterfaceDefaultRoute: 2001:db8:fd00:1000::1

View File

@ -7,14 +7,14 @@ p3
(dp4
S'route'
p5
V192.0.2.1
V192.168.24.1
p6
sS'mask'
p7
I24
sS'ec2'
p8
V192.0.2.1
V192.168.24.1
p9
ssS'major'
p10

View File

@ -8,8 +8,8 @@ resource_registry:
parameter_defaults:
ControlPlaneSubnetCidr: '24'
ControlPlaneDefaultRoute: 192.0.2.1
EC2MetadataIp: 192.0.2.1
ControlPlaneDefaultRoute: 192.168.24.1
EC2MetadataIp: 192.168.24.1
ExternalNetCidr: 10.0.0.0/24
ExternalAllocationPools: [{"start": "10.0.0.10", "end": "10.0.0.50"}]
ExternalInterfaceDefaultRoute: 10.0.0.1

View File

@ -7,14 +7,14 @@ p3
(dp4
S'route'
p5
V192.0.2.1
V192.168.24.1
p6
sS'mask'
p7
I24
sS'ec2'
p8
V192.0.2.1
V192.168.24.1
p9
ssS'major'
p10

View File

@ -117,3 +117,5 @@ outputs:
storage_net: {get_resource: storage_network}
storage_mgmt_net: {get_resource: storage_mgmt_network}
tenant_net: {get_resource: tenant_network}
routers_addresses:
value: {}

View File

@ -3,3 +3,5 @@ heat_template_version: 2014-10-16
outputs:
networks:
value: {}
routers_addresses:
value: {}

View File

@ -16,6 +16,11 @@ parameters:
does not need to be changed.
default: 172.17.0.0/24
overcloud_internal_net_router_address:
type: string
description: Router address for the overcloud_internal_net
default: 172.17.0.254
overcloud_internal_net2:
type: string
description: Name of internal API network
@ -28,6 +33,11 @@ parameters:
does not need to be changed.
default: 172.17.1.0/24
overcloud_internal_net2_router_address:
type: string
description: Router address for the overcloud_internal_net2 subnet
default: 172.17.1.254
overcloud_storage_net:
type: string
description: Name of storage network
@ -40,6 +50,11 @@ parameters:
does not need to be changed.
default: 172.18.0.0/24
overcloud_storage_net_router_address:
type: string
description: Router address for the overcloud_storage_net subnet
default: 172.18.0.254
overcloud_storage_net2:
type: string
description: Name of storage network
@ -52,6 +67,11 @@ parameters:
does not need to be changed.
default: 172.18.1.0/24
overcloud_storage_net2_router_address:
type: string
description: Router address for the overcloud_storage_net2 subnet
default: 172.18.1.254
overcloud_storage_mgmt_net:
type: string
description: Name of storage management network
@ -64,6 +84,11 @@ parameters:
and does not need to be changed.
default: 172.19.0.0/24
overcloud_storage_mgmt_net_router_address:
type: string
description: Router address for the overcloud_storage_mgmt_net subnet
default: 172.19.0.254
overcloud_storage_mgmt_net2:
type: string
description: Name of storage management network
@ -76,6 +101,11 @@ parameters:
and does not need to be changed.
default: 172.19.1.0/24
overcloud_storage_mgmt_net2_router_address:
type: string
description: Router address for the overcloud_storage_mgmt_net2 subnet
default: 172.19.1.254
overcloud_tenant_net:
type: string
description: Name of tenant network
@ -88,6 +118,11 @@ parameters:
does not need to be changed.
default: 172.16.0.0/24
overcloud_tenant_net_router_address:
type: string
description: Router address for the overcloud_tenant_net subnet
default: 172.16.0.254
overcloud_tenant_net2:
type: string
description: Name of tenant network
@ -100,6 +135,11 @@ parameters:
does not need to be changed.
default: 172.16.1.0/24
overcloud_tenant_net2_router_address:
type: string
description: Router address for the overcloud_tenant_net2 subnet
default: 172.16.1.254
resources:
internal_router:
type: OS::Neutron::Router
@ -125,6 +165,8 @@ resources:
properties:
network: {get_resource: internal_network}
port_security_enabled: false
fixed_ips:
- ip_address: {get_param: overcloud_internal_net_router_address}
internal_subnet_interface:
type: OS::Neutron::RouterInterface
@ -151,6 +193,8 @@ resources:
properties:
network: {get_resource: internal_network2}
port_security_enabled: false
fixed_ips:
- ip_address: {get_param: overcloud_internal_net2_router_address}
internal_subnet2_interface:
type: OS::Neutron::RouterInterface
@ -182,6 +226,8 @@ resources:
properties:
network: {get_resource: storage_network}
port_security_enabled: false
fixed_ips:
- ip_address: {get_param: overcloud_storage_net_router_address}
storage_subnet_interface:
type: OS::Neutron::RouterInterface
@ -208,6 +254,8 @@ resources:
properties:
network: {get_resource: storage_network2}
port_security_enabled: false
fixed_ips:
- ip_address: {get_param: overcloud_storage_net2_router_address}
storage_subnet2_interface:
type: OS::Neutron::RouterInterface
@ -239,6 +287,8 @@ resources:
properties:
network: {get_resource: storage_mgmt_network}
port_security_enabled: false
fixed_ips:
- ip_address: {get_param: overcloud_storage_mgmt_net_router_address}
storage_mgmt_subnet_interface:
type: OS::Neutron::RouterInterface
@ -265,6 +315,8 @@ resources:
properties:
network: {get_resource: storage_mgmt_network2}
port_security_enabled: false
fixed_ips:
- ip_address: {get_param: overcloud_storage_mgmt_net2_router_address}
storage_mgmt_subnet2_interface:
type: OS::Neutron::RouterInterface
@ -296,6 +348,8 @@ resources:
properties:
network: {get_resource: tenant_network}
port_security_enabled: false
fixed_ips:
- ip_address: {get_param: overcloud_tenant_net_router_address}
tenant_subnet_interface:
type: OS::Neutron::RouterInterface
@ -322,6 +376,8 @@ resources:
properties:
network: {get_resource: tenant_network2}
port_security_enabled: false
fixed_ips:
- ip_address: {get_param: overcloud_tenant_net2_router_address}
tenant_subnet2_interface:
type: OS::Neutron::RouterInterface
@ -340,3 +396,13 @@ outputs:
storage_mgmt_net2: {get_resource: storage_mgmt_network2}
tenant_net: {get_resource: tenant_network}
tenant_net2: {get_resource: tenant_network2}
routers_addresses:
value:
internal_router_address: {get_attr: [internal_subnet_port, fixed_ips, 0, ip_address]}
internal2_router: {get_attr: [internal_subnet2_port, fixed_ips, 0, ip_address]}
storage_router_address: {get_attr: [storage_subnet_port, fixed_ips, 0, ip_address]}
storage2_router_address: {get_attr: [storage_subnet2_port, fixed_ips, 0, ip_address]}
storage_mgmt_router_address: {get_attr: [storage_mgmt_subnet_port, fixed_ips, 0, ip_address]}
storage_mgmt2_router_address: {get_attr: [storage_mgmt_subnet2_port, fixed_ips, 0, ip_address]}
tenant_router_address: {get_attr: [tenant_subnet_port, fixed_ips, 0, ip_address]}
tenant2_router_address: {get_attr: [tenant_subnet2_port, fixed_ips, 0, ip_address]}

View File

@ -19,20 +19,10 @@ parameters:
The base image for the dhcrelay instance. A CentOS 7 image is currently
the only one supported.
inspector_dhcp_ip:
type: string
default: 172.20.0.1
dhcp_ips:
type: json
description: |
The IP address on the undercloud provisioning network. 'local_ip' in
undercloud.conf
provision_dhcp_ip:
type: string
default: 172.20.0.10
description: |
The IP address on the undercloud provisioning network.
(The first address in the underclouds local_subnet allocation range.
I.e the dhcp_start address)
The IP addresses of DHCP servers to relay DHCP requests to.
networks:
type: json
@ -125,14 +115,16 @@ resources:
[Service]
Type=simple
ExecStart=/usr/sbin/dhcrelay -d --no-pid $provision_dhcp_ip $inspector_dhcp_ip -i eth1 -i eth2 -i eth3
ExecStart=/usr/sbin/dhcrelay -d --no-pid $dhcp_ips -i eth1 -i eth2 -i eth3
StandardError=null
[Install]
WantedBy=multi-user.target
params:
$provision_dhcp_ip: {get_param: provision_dhcp_ip}
$inspector_dhcp_ip: {get_param: inspector_dhcp_ip}
$dhcp_ips:
list_join:
- ' '
- {get_param: dhcp_ips}
- path: /etc/sysctl.d/98-rp-filter.conf
content: |
net.ipv4.conf.eth1.rp_filter = 0

View File

@ -1,4 +1,4 @@
heat_template_version: 2015-04-30
heat_template_version: 2016-04-08
# Template that wraps virtual-baremetal.yaml and does some additional environment
# setup automatically:
@ -141,6 +141,13 @@ parameters:
ignored by Heat, but used by build-nodes-json.
default: ''
dhcp_ips:
type: json
default:
- 192.168.24.1
- 192.168.24.10
description: |
The IP addresses of DHCP servers to relay DHCP requests to.
resources:
undercloud_networks:
@ -188,6 +195,7 @@ resources:
os_user_domain: {get_param: os_user_domain}
os_project_domain: {get_param: os_project_domain}
cloud_data: {get_param: cloud_data}
dhcp_ips: {get_param: dhcp_ips}
outputs:
undercloud_host_floating_ip:
@ -198,3 +206,9 @@ outputs:
description: "ip of the undercloud instance on the private network"
value:
get_attr: [undercloud_env, undercloud_host_private_ip]
network_environment_data:
description: "Network environment data, router addresses etc."
value:
map_merge:
- get_attr: [undercloud_networks, provision_network_routers]
- get_attr: [baremetal_env, baremetal_networks_routers_addresses]

View File

@ -9,7 +9,12 @@ parameters:
provision_net_cidr:
type: string
description: CIDR for provision network subnet
default: 192.0.2.0/24
default: 192.168.24.0/24
provision_net_router_address:
type: string
description: Router address for the provision network subnet
default: 192.168.24.254
provision_net_shared:
type: boolean
@ -24,7 +29,12 @@ parameters:
provision_net2_cidr:
type: string
description: CIDR for second provision network subnet
default: 192.0.3.0/24
default: 192.168.25.0/24
provision_net2_router_address:
type: string
description: Router address for the provision network subnet
default: 192.168.25.254
provision_net2_shared:
type: boolean
@ -39,7 +49,12 @@ parameters:
provision_net3_cidr:
type: string
description: CIDR for third provision network subnet
default: 192.0.4.0/24
default: 192.168.26.0/24
provision_net3_router_address:
type: string
description: Router address for the provision network subnet
default: 192.168.26.254
provision_net3_shared:
type: boolean
@ -87,6 +102,8 @@ resources:
properties:
network: {get_resource: provision_network}
port_security_enabled: false
fixed_ips:
- ip_address: {get_param: provision_net_router_address}
provision_router_interface:
type: OS::Neutron::RouterInterface
@ -114,6 +131,8 @@ resources:
properties:
network: {get_resource: provision_network2}
port_security_enabled: false
fixed_ips:
- ip_address: {get_param: provision_net2_router_address}
provision_router_interface2:
type: OS::Neutron::RouterInterface
@ -141,6 +160,8 @@ resources:
properties:
network: {get_resource: provision_network3}
port_security_enabled: false
fixed_ips:
- ip_address: {get_param: provision_net3_router_address}
provision_router_interface3:
type: OS::Neutron::RouterInterface
@ -170,3 +191,8 @@ outputs:
provision2: {get_resource: provision_network2}
provision3: {get_resource: provision_network3}
public: {get_resource: public_network}
provision_network_routers:
value:
provision_router: {get_attr: [provision_router_port, fixed_ips, 0, ip_address]}
provision2_router: {get_attr: [provision_router_port2, fixed_ips, 0, ip_address]}
provision3_router: {get_attr: [provision_router_port3, fixed_ips, 0, ip_address]}

View File

@ -9,7 +9,7 @@ parameters:
provision_net_cidr:
type: string
description: CIDR for provision network subnet
default: 192.0.2.0/24
default: 192.168.24.0/24
provision_net_shared:
type: boolean
@ -67,3 +67,6 @@ outputs:
value:
provision: {get_resource: provision_network}
public: {get_resource: public_network}
# The provision_network_routers is here for compatibility only
provision_network_routers:
value: {}

View File

@ -52,7 +52,7 @@ parameters:
networks:
type: json
default: '{"private": "private", "provision": "provision"}'
default: {"private": "private", "provision": "provision"}
description: A map of networks to their names.
bmc_prefix:
@ -114,6 +114,14 @@ parameters:
default: '{}'
hidden: true
dhcp_ips:
type: json
default:
- 192.168.24.1
- 192.168.24.10
description: |
The IP addresses of DHCP servers to relay DHCP requests to.
# Ignored parameters for compatibility with QuintupleO env files
undercloud_image:
type: string
@ -207,3 +215,8 @@ resources:
type: OS::OVB::DHCPRelay
properties:
networks: {get_param: networks}
dhcp_ips: {get_param: dhcp_ips}
outputs:
baremetal_networks_routers_addresses:
value: {get_attr: [baremetal_networks, routers_addresses]}