Add option to strip '--id' from physical_network

When using routed networks it is required to set the
physical_network property for baremetal ports. The
'--physical-network' option makes the build-nodes-json
command add this.

Whith this change the '--id' arg can be used with the
build-nodes-json command to strip the id added with the
deploy commands '--id' option from the resource name
when setting the physical_network property.

Usage:
 ovb-build-nodes-json --env my-env.yaml \
   --nodes_json instackenv.json \
   --physical_network \
   --id <ID-to-strip>

Change-Id: Ic5fea591464a9f8bb91bcaef9a99d0b9e994e19e
This commit is contained in:
Harald Jensås 2020-10-20 14:29:52 +02:00
parent 677467cd27
commit 2a08c50da8
2 changed files with 162 additions and 24 deletions

View File

@ -16,6 +16,7 @@
import argparse
import json
import os
import re
import yaml
import os_client_config
@ -66,6 +67,11 @@ def _parse_args():
action='store_true',
help='Set the physical network attribute of baremetal '
'ports. (Requires Rocky or later Ironic)')
parser.add_argument('--id',
help='Identifier to remove from network resource '
'names when setting physical network attribute '
'of baremetal ports. (This should match the --id '
'used with for the ovb-deploy command.)')
args = parser.parse_args()
return args
@ -117,9 +123,9 @@ def _get_ports(neutron, bmc_base, baremetal_base):
def _build_nodes(nova, glance, bmc_ports, bm_ports, provision_net_map,
baremetal_base, undercloud_name, driver, physical_network):
baremetal_base, undercloud_name, args):
node_template = {
'pm_type': driver,
'pm_type': args.driver,
'mac': '',
'cpu': '',
'memory': '',
@ -131,7 +137,7 @@ def _build_nodes(nova, glance, bmc_ports, bm_ports, provision_net_map,
'capabilities': 'boot_option:local',
'name': '',
}
if physical_network:
if args.physical_network:
node_template.pop('mac')
nodes = []
cache = {}
@ -145,9 +151,14 @@ def _build_nodes(nova, glance, bmc_ports, bm_ports, provision_net_map,
node['pm_addr'] = bmc_port['fixed_ips'][0]['ip_address']
provision_net = provision_net_map.get(baremetal_port['id'])
mac = baremetal.addresses[provision_net][0]['OS-EXT-IPS-MAC:mac_addr']
if physical_network:
if args.physical_network:
if args.id:
physical_network = re.sub('-' + args.id + '$', '',
provision_net)
else:
physical_network = provision_net
node.update({'ports': [{'address': mac,
'physical_network': provision_net}]})
'physical_network': physical_network}]})
else:
node['mac'] = [mac]
if not cache.get(baremetal.flavor['id']):
@ -268,8 +279,7 @@ def main():
extra_nodes,
network_details) = _build_nodes(nova, glance, bmc_ports, bm_ports,
provision_net_map, baremetal_base,
undercloud_name, args.driver,
args.physical_network)
undercloud_name, args)
_write_nodes(nodes, extra_nodes, network_details, args)
_write_role_nodes(nodes, args)

View File

@ -255,20 +255,21 @@ class TestBuildNodesJson(testtools.TestCase):
'fixed_ips': [{'ip_address': ip}],
}
def _create_build_nodes_mocks(self, nova, servers):
def _create_build_nodes_mocks(self, nova, servers,
provision_net='provision'):
nova.servers.get.side_effect = servers
servers[0].name = 'bm_0'
servers[0].flavor = {'id': '1'}
servers[0].addresses = {'provision': [{'OS-EXT-IPS-MAC:mac_addr':
'aa:aa:aa:aa:aa:aa',
'addr': '2.1.1.1'}]}
servers[0].addresses = {provision_net: [
{'OS-EXT-IPS-MAC:mac_addr': 'aa:aa:aa:aa:aa:aa',
'addr': '2.1.1.1'}]}
servers[0].image = {'id': 'f00'}
servers[0].id = '123abc'
servers[1].name = 'bm_1'
servers[1].flavor = {'id': '1'}
servers[1].addresses = {'provision': [{'OS-EXT-IPS-MAC:mac_addr':
'aa:aa:aa:aa:aa:ab',
'addr': '2.1.1.2'}]}
servers[1].addresses = {provision_net: [
{'OS-EXT-IPS-MAC:mac_addr': 'aa:aa:aa:aa:aa:ab',
'addr': '2.1.1.2'}]}
servers[1].image = {'id': 'f00'}
servers[1].id = '456def'
mock_flavor = mock.Mock()
@ -279,6 +280,10 @@ class TestBuildNodesJson(testtools.TestCase):
@mock.patch('os_client_config.make_client')
def test_build_nodes(self, mock_make_client):
args = mock.Mock()
args.physical_network = False
args.driver = 'pxe_ipmitool'
args.id = False
bmc_ports = [{'fixed_ips': [{'ip_address': '1.1.1.1'}]},
{'fixed_ips': [{'ip_address': '1.1.1.2'}]}
]
@ -287,7 +292,6 @@ class TestBuildNodesJson(testtools.TestCase):
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()]
self._create_build_nodes_mocks(nova, servers)
@ -315,7 +319,7 @@ class TestBuildNodesJson(testtools.TestCase):
extra_nodes,
network_details) = build_nodes_json._build_nodes(
nova, glance, bmc_ports, bm_ports, provision_net_map, 'bm',
'undercloud', 'pxe_ipmitool', physical_network)
'undercloud', args)
expected_nodes = copy.deepcopy(TEST_NODES)
expected_nodes[1]['disk'] = 100
self.assertEqual(expected_nodes, nodes)
@ -328,6 +332,10 @@ class TestBuildNodesJson(testtools.TestCase):
@mock.patch('os_client_config.make_client')
def test_build_nodes_with_driver(self, mock_make_client):
args = mock.Mock()
args.physical_network = False
args.driver = 'ipmi'
args.id = False
bmc_ports = [{'fixed_ips': [{'ip_address': '1.1.1.1'}]},
{'fixed_ips': [{'ip_address': '1.1.1.2'}]}
]
@ -336,7 +344,6 @@ class TestBuildNodesJson(testtools.TestCase):
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()]
self._create_build_nodes_mocks(nova, servers)
@ -364,7 +371,7 @@ class TestBuildNodesJson(testtools.TestCase):
extra_nodes,
network_details) = build_nodes_json._build_nodes(
nova, glance, bmc_ports, bm_ports, provision_net_map, 'bm',
'undercloud', 'ipmi', physical_network)
'undercloud', args)
expected_nodes = copy.deepcopy(TEST_NODES)
expected_nodes[1]['disk'] = 100
for node in expected_nodes:
@ -378,6 +385,11 @@ class TestBuildNodesJson(testtools.TestCase):
'2.1.1.2', network_details['bm_1']['ips']['provision'][0]['addr'])
def test_build_nodes_role_uefi(self):
args = mock.Mock()
args.physical_network = False
args.driver = 'pxe_ipmitool'
args.id = False
bmc_ports = [{'fixed_ips': [{'ip_address': '1.1.1.1'}]},
{'fixed_ips': [{'ip_address': '1.1.1.2'}]}
]
@ -386,7 +398,6 @@ class TestBuildNodesJson(testtools.TestCase):
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()]
self._create_build_nodes_mocks(nova, servers)
@ -402,7 +413,7 @@ class TestBuildNodesJson(testtools.TestCase):
nodes, extra_nodes, _ = build_nodes_json._build_nodes(
nova, glance, bmc_ports, bm_ports, provision_net_map, 'bm-foo',
None, 'pxe_ipmitool', physical_network)
None, args)
expected_nodes = copy.deepcopy(TEST_NODES)
expected_nodes[0]['name'] = 'bm-foo-control-0'
expected_nodes[0]['capabilities'] = ('boot_option:local,'
@ -414,6 +425,125 @@ class TestBuildNodesJson(testtools.TestCase):
'profile:control')
self.assertEqual(expected_nodes, nodes)
@mock.patch('os_client_config.make_client')
def test_build_nodes_with_physnet(self, mock_make_client):
args = mock.Mock()
args.physical_network = True
args.driver = 'pxe_ipmitool'
args.id = False
bmc_ports = [{'fixed_ips': [{'ip_address': '1.1.1.1'}]},
{'fixed_ips': [{'ip_address': '1.1.1.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', }
nova = mock.Mock()
servers = [mock.Mock(), mock.Mock(), mock.Mock()]
self._create_build_nodes_mocks(nova, servers)
servers[1].image = None
mock_to_dict = {'os-extended-volumes:volumes_attached':
[{'id': 'v0lume'}]}
servers[1].to_dict.return_value = mock_to_dict
mock_cinder = mock.Mock()
mock_make_client.return_value = mock_cinder
mock_vol = mock.Mock()
mock_vol.size = 100
mock_cinder.volumes.get.return_value = mock_vol
servers[2].name = 'undercloud'
servers[2].flavor = {'id': '1'}
servers[2].addresses = {'provision': [{'OS-EXT-IPS-MAC:mac_addr':
'aa:aa:aa:aa:aa:ac'}]}
servers[2].image = {'id': 'f00'}
nova.servers.list.return_value = [servers[2]]
ips_return_val = 'ips call value'
nova.servers.ips.return_value = ips_return_val
glance = mock.Mock()
(nodes,
extra_nodes,
network_details) = build_nodes_json._build_nodes(
nova, glance, bmc_ports, bm_ports, provision_net_map, 'bm',
'undercloud', args)
expected_nodes = copy.deepcopy(TEST_NODES)
expected_nodes[1]['disk'] = 100
node0_mac = expected_nodes[0].pop('mac')
node1_mac = expected_nodes[1].pop('mac')
expected_nodes[0]['ports'] = [{'address': node0_mac[0],
'physical_network': 'provision'}]
expected_nodes[1]['ports'] = [{'address': node1_mac[0],
'physical_network': 'provision'}]
self.assertEqual(expected_nodes, nodes)
self.assertEqual(1, len(extra_nodes))
self.assertEqual('undercloud', extra_nodes[0]['name'])
self.assertEqual(
'2.1.1.1', network_details['bm_0']['ips']['provision'][0]['addr'])
self.assertEqual(
'2.1.1.2', network_details['bm_1']['ips']['provision'][0]['addr'])
@mock.patch('os_client_config.make_client')
def test_build_nodes_with_physnet_strip_id(self, mock_make_client):
args = mock.Mock()
args.physical_network = True
args.driver = 'pxe_ipmitool'
args.id = '123'
bmc_ports = [{'fixed_ips': [{'ip_address': '1.1.1.1'}]},
{'fixed_ips': [{'ip_address': '1.1.1.2'}]}
]
bm_ports = [{'device_id': '1', 'id': 'port_id_server1'},
{'device_id': '2', 'id': 'port_id_server2'}]
provision_net_map = {'port_id_server1': 'ctlplane-123',
'port_id_server2': 'ctlplane-123',
'port_id_server3': 'ctlplane-123', }
nova = mock.Mock()
servers = [mock.Mock(), mock.Mock(), mock.Mock()]
self._create_build_nodes_mocks(nova, servers,
provision_net='ctlplane-123')
servers[1].image = None
mock_to_dict = {'os-extended-volumes:volumes_attached':
[{'id': 'v0lume'}]}
servers[1].to_dict.return_value = mock_to_dict
mock_cinder = mock.Mock()
mock_make_client.return_value = mock_cinder
mock_vol = mock.Mock()
mock_vol.size = 100
mock_cinder.volumes.get.return_value = mock_vol
servers[2].name = 'undercloud'
servers[2].flavor = {'id': '1'}
servers[2].addresses = {'ctlplane-123': [
{'OS-EXT-IPS-MAC:mac_addr': 'aa:aa:aa:aa:aa:ac'}]}
servers[2].image = {'id': 'f00'}
nova.servers.list.return_value = [servers[2]]
ips_return_val = 'ips call value'
nova.servers.ips.return_value = ips_return_val
glance = mock.Mock()
(nodes,
extra_nodes,
network_details) = build_nodes_json._build_nodes(
nova, glance, bmc_ports, bm_ports, provision_net_map, 'bm',
'undercloud', args)
expected_nodes = copy.deepcopy(TEST_NODES)
expected_nodes[1]['disk'] = 100
node0_mac = expected_nodes[0].pop('mac')
node1_mac = expected_nodes[1].pop('mac')
expected_nodes[0]['ports'] = [{'address': node0_mac[0],
'physical_network': 'ctlplane'}]
expected_nodes[1]['ports'] = [{'address': node1_mac[0],
'physical_network': 'ctlplane'}]
self.assertEqual(expected_nodes, nodes)
self.assertEqual(1, len(extra_nodes))
self.assertEqual('undercloud', extra_nodes[0]['name'])
self.assertEqual(
'2.1.1.1',
network_details['bm_0']['ips']['ctlplane-123'][0]['addr'])
self.assertEqual(
'2.1.1.2',
network_details['bm_1']['ips']['ctlplane-123'][0]['addr'])
@mock.patch('openstack_virtual_baremetal.build_nodes_json.open',
create=True)
def test_write_nodes(self, mock_open):
@ -502,8 +632,7 @@ class TestBuildNodesJson(testtools.TestCase):
nodes = mock.Mock()
extra_nodes = mock.Mock()
network_details = mock.Mock()
mock_build_nodes.return_value = (nodes, extra_nodes,
network_details)
mock_build_nodes.return_value = (nodes, extra_nodes, network_details)
build_nodes_json.main()
@ -516,8 +645,7 @@ class TestBuildNodesJson(testtools.TestCase):
bm_ports, provision_net_map,
baremetal_base,
undercloud_name,
args.driver,
args.physical_network)
args)
mock_write_nodes.assert_called_once_with(nodes, extra_nodes,
network_details, args)
mock_write_role_nodes.assert_called_once_with(nodes, args)