ctlplane network attributes in overcloud environment
Set CtlplaneNetworkAttributes parameter in overcloud environment. The parameter contains a map with network and subnets data. CtlplaneNetworkAttributes: network: dns_domain: ctlplane.localdomain. mtu: 1442 name: ctlplane tags: ['192.168.24.0/24', '192.168.25.0/24'] subnets: ctlplane-leaf1: cidr: 192.168.25.0/24 dns_nameservers: ['8.8.8.8', '8.8.4.4'] gateway_ip: 192.168.25.254 host_routes: - {'destination': '192.168.24.0/24', 'nexthop': '192.168.25.254'} ip_version: 4 name: ctlplane-leaf1 Also set the CtlplaneNetworkAttributes in the undercloud environment from the data in undercloud.conf. Also set the CtlplaneNetworkAttributes in the standalone environment. Change-Id: I12f1ea965d489eb36353e988cc3ec947f72a35ad
This commit is contained in:
parent
04e9966b7f
commit
6ced9c71db
|
@ -57,7 +57,7 @@ munch==2.1.0
|
||||||
netaddr==0.7.18
|
netaddr==0.7.18
|
||||||
netifaces==0.10.4
|
netifaces==0.10.4
|
||||||
networkx==1.10
|
networkx==1.10
|
||||||
openstacksdk==0.11.2
|
openstacksdk==0.48.0
|
||||||
os-client-config==1.28.0
|
os-client-config==1.28.0
|
||||||
os-service-types==1.2.0
|
os-service-types==1.2.0
|
||||||
osc-lib==1.8.0
|
osc-lib==1.8.0
|
||||||
|
|
|
@ -18,3 +18,4 @@ tripleo-common>=12.6.0 # Apache-2.0
|
||||||
cryptography>=2.1 # BSD/Apache-2.0
|
cryptography>=2.1 # BSD/Apache-2.0
|
||||||
ansible-runner>=1.4.5 # Apache 2.0
|
ansible-runner>=1.4.5 # Apache 2.0
|
||||||
validations-libs>=1.0.0
|
validations-libs>=1.0.0
|
||||||
|
openstacksdk>=0.48.0 # Apache-2.0
|
||||||
|
|
|
@ -108,3 +108,84 @@ class TestDeployOvercloud(fakes.FakePlaybookExecution):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestDeployOvercloud, self).setUp(ansible_mock=False)
|
super(TestDeployOvercloud, self).setUp(ansible_mock=False)
|
||||||
|
|
||||||
|
|
||||||
|
class FakeNeutronNetwork(dict):
|
||||||
|
def __init__(self, **attrs):
|
||||||
|
NETWORK_ATTRS = ['id',
|
||||||
|
'name',
|
||||||
|
'status',
|
||||||
|
'tenant_id',
|
||||||
|
'is_admin_state_up',
|
||||||
|
'mtu',
|
||||||
|
'segments',
|
||||||
|
'is_shared',
|
||||||
|
'subnet_ids',
|
||||||
|
'provider:network_type',
|
||||||
|
'provider:physical_network',
|
||||||
|
'provider:segmentation_id',
|
||||||
|
'router:external',
|
||||||
|
'availability_zones',
|
||||||
|
'availability_zone_hints',
|
||||||
|
'is_default',
|
||||||
|
'tags']
|
||||||
|
|
||||||
|
raw = dict.fromkeys(NETWORK_ATTRS)
|
||||||
|
raw.update(attrs)
|
||||||
|
raw.update({
|
||||||
|
'provider_physical_network': attrs.get(
|
||||||
|
'provider:physical_network', None),
|
||||||
|
'provider_network_type': attrs.get(
|
||||||
|
'provider:network_type', None),
|
||||||
|
'provider_segmentation_id': attrs.get(
|
||||||
|
'provider:segmentation_id', None)
|
||||||
|
})
|
||||||
|
super(FakeNeutronNetwork, self).__init__(raw)
|
||||||
|
|
||||||
|
def __getattr__(self, key):
|
||||||
|
try:
|
||||||
|
return self[key]
|
||||||
|
except KeyError:
|
||||||
|
raise AttributeError(key)
|
||||||
|
|
||||||
|
def __setattr__(self, key, value):
|
||||||
|
if key in self:
|
||||||
|
self[key] = value
|
||||||
|
else:
|
||||||
|
raise AttributeError(key)
|
||||||
|
|
||||||
|
|
||||||
|
class FakeNeutronSubnet(dict):
|
||||||
|
def __init__(self, **attrs):
|
||||||
|
SUBNET_ATTRS = ['id',
|
||||||
|
'name',
|
||||||
|
'network_id',
|
||||||
|
'cidr',
|
||||||
|
'tenant_id',
|
||||||
|
'is_dhcp_enabled',
|
||||||
|
'dns_nameservers',
|
||||||
|
'allocation_pools',
|
||||||
|
'host_routes',
|
||||||
|
'ip_version',
|
||||||
|
'gateway_ip',
|
||||||
|
'ipv6_address_mode',
|
||||||
|
'ipv6_ra_mode',
|
||||||
|
'subnetpool_id',
|
||||||
|
'segment_id',
|
||||||
|
'tags']
|
||||||
|
|
||||||
|
raw = dict.fromkeys(SUBNET_ATTRS)
|
||||||
|
raw.update(attrs)
|
||||||
|
super(FakeNeutronSubnet, self).__init__(raw)
|
||||||
|
|
||||||
|
def __getattr__(self, key):
|
||||||
|
try:
|
||||||
|
return self[key]
|
||||||
|
except KeyError:
|
||||||
|
raise AttributeError(key)
|
||||||
|
|
||||||
|
def __setattr__(self, key, value):
|
||||||
|
if key in self:
|
||||||
|
self[key] = value
|
||||||
|
else:
|
||||||
|
raise AttributeError(key)
|
||||||
|
|
|
@ -22,6 +22,7 @@ import yaml
|
||||||
|
|
||||||
from heatclient import exc as hc_exc
|
from heatclient import exc as hc_exc
|
||||||
import mock
|
import mock
|
||||||
|
import openstack
|
||||||
from osc_lib import exceptions as oscexc
|
from osc_lib import exceptions as oscexc
|
||||||
from osc_lib.tests import utils
|
from osc_lib.tests import utils
|
||||||
from swiftclient.exceptions import ClientException as ObjectClientException
|
from swiftclient.exceptions import ClientException as ObjectClientException
|
||||||
|
@ -170,6 +171,8 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
|
||||||
self.cmd._download_missing_files_from_plan = self.real_download_missing
|
self.cmd._download_missing_files_from_plan = self.real_download_missing
|
||||||
shutil.rmtree = self.real_shutil
|
shutil.rmtree = self.real_shutil
|
||||||
|
|
||||||
|
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
|
||||||
|
'_get_ctlplane_attrs', autospec=True, return_value={})
|
||||||
@mock.patch('tripleoclient.utils.copy_clouds_yaml')
|
@mock.patch('tripleoclient.utils.copy_clouds_yaml')
|
||||||
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
|
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
|
||||||
'_get_undercloud_host_entry', autospec=True,
|
'_get_undercloud_host_entry', autospec=True,
|
||||||
|
@ -189,7 +192,8 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
|
||||||
mock_create_parameters_env,
|
mock_create_parameters_env,
|
||||||
mock_breakpoints_cleanup,
|
mock_breakpoints_cleanup,
|
||||||
mock_events, mock_stack_network_check,
|
mock_events, mock_stack_network_check,
|
||||||
mock_get_undercloud_host_entry, mock_copy):
|
mock_get_undercloud_host_entry, mock_copy,
|
||||||
|
mock_get_ctlplane_attrs):
|
||||||
fixture = deployment.DeploymentWorkflowFixture()
|
fixture = deployment.DeploymentWorkflowFixture()
|
||||||
self.useFixture(fixture)
|
self.useFixture(fixture)
|
||||||
clients = self.app.client_manager
|
clients = self.app.client_manager
|
||||||
|
@ -241,7 +245,8 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
|
||||||
'SnmpdReadonlyUserPassword': 'PASSWORD',
|
'SnmpdReadonlyUserPassword': 'PASSWORD',
|
||||||
'StackAction': 'UPDATE',
|
'StackAction': 'UPDATE',
|
||||||
'UndercloudHostsEntries': [
|
'UndercloudHostsEntries': [
|
||||||
'192.168.0.1 uc.ctlplane.localhost uc.ctlplane']
|
'192.168.0.1 uc.ctlplane.localhost uc.ctlplane'],
|
||||||
|
'CtlplaneNetworkAttributes': {},
|
||||||
}
|
}
|
||||||
|
|
||||||
def _custom_create_params_env(_self, parameters, tht_root,
|
def _custom_create_params_env(_self, parameters, tht_root,
|
||||||
|
@ -266,6 +271,8 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
|
||||||
object_client.put_container.assert_called_once_with(
|
object_client.put_container.assert_called_once_with(
|
||||||
'overcloud', headers={'x-container-meta-usage-tripleo': 'plan'})
|
'overcloud', headers={'x-container-meta-usage-tripleo': 'plan'})
|
||||||
|
|
||||||
|
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
|
||||||
|
'_get_ctlplane_attrs', autospec=True, return_value={})
|
||||||
@mock.patch('tripleoclient.workflows.deployment.create_overcloudrc',
|
@mock.patch('tripleoclient.workflows.deployment.create_overcloudrc',
|
||||||
autospec=True)
|
autospec=True)
|
||||||
@mock.patch('tripleoclient.utils.copy_clouds_yaml')
|
@mock.patch('tripleoclient.utils.copy_clouds_yaml')
|
||||||
|
@ -290,7 +297,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
|
||||||
mock_breakpoints_cleanup, mock_postconfig,
|
mock_breakpoints_cleanup, mock_postconfig,
|
||||||
mock_invoke_plan_env_wf,
|
mock_invoke_plan_env_wf,
|
||||||
mock_get_undercloud_host_entry,
|
mock_get_undercloud_host_entry,
|
||||||
mock_copy, mock_overcloudrc):
|
mock_copy, mock_overcloudrc, mock_get_ctlplane_attrs):
|
||||||
|
|
||||||
fixture = deployment.DeploymentWorkflowFixture()
|
fixture = deployment.DeploymentWorkflowFixture()
|
||||||
self.useFixture(fixture)
|
self.useFixture(fixture)
|
||||||
|
@ -337,7 +344,8 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
|
||||||
'parameter_defaults': {
|
'parameter_defaults': {
|
||||||
'StackAction': 'CREATE',
|
'StackAction': 'CREATE',
|
||||||
'UndercloudHostsEntries':
|
'UndercloudHostsEntries':
|
||||||
['192.168.0.1 uc.ctlplane.localhost uc.ctlplane']}}
|
['192.168.0.1 uc.ctlplane.localhost uc.ctlplane'],
|
||||||
|
'CtlplaneNetworkAttributes': {}}}
|
||||||
|
|
||||||
mock_open_context = mock.mock_open()
|
mock_open_context = mock.mock_open()
|
||||||
with mock.patch('six.moves.builtins.open', mock_open_context):
|
with mock.patch('six.moves.builtins.open', mock_open_context):
|
||||||
|
@ -378,6 +386,8 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
|
||||||
object_client = clients.tripleoclient.object_store
|
object_client = clients.tripleoclient.object_store
|
||||||
object_client.put_object.assert_has_calls(calls)
|
object_client.put_object.assert_has_calls(calls)
|
||||||
|
|
||||||
|
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
|
||||||
|
'_get_ctlplane_attrs', autospec=True, return_value={})
|
||||||
@mock.patch('os.chdir')
|
@mock.patch('os.chdir')
|
||||||
@mock.patch('tripleoclient.utils.copy_clouds_yaml')
|
@mock.patch('tripleoclient.utils.copy_clouds_yaml')
|
||||||
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
|
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
|
||||||
|
@ -410,7 +420,8 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
|
||||||
mock_postconfig, mock_shutil_rmtree,
|
mock_postconfig, mock_shutil_rmtree,
|
||||||
mock_invoke_plan_env_wf,
|
mock_invoke_plan_env_wf,
|
||||||
mock_stack_network_check,
|
mock_stack_network_check,
|
||||||
mock_get_undercloud_host_entry, mock_copy, mock_chdir):
|
mock_get_undercloud_host_entry, mock_copy, mock_chdir,
|
||||||
|
mock_get_ctlplane_attrs):
|
||||||
fixture = deployment.DeploymentWorkflowFixture()
|
fixture = deployment.DeploymentWorkflowFixture()
|
||||||
self.useFixture(fixture)
|
self.useFixture(fixture)
|
||||||
plane_management_fixture = deployment.PlanManagementFixture()
|
plane_management_fixture = deployment.PlanManagementFixture()
|
||||||
|
@ -468,7 +479,8 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
|
||||||
'StackAction': 'CREATE',
|
'StackAction': 'CREATE',
|
||||||
'UndercloudHostsEntries': [
|
'UndercloudHostsEntries': [
|
||||||
'192.168.0.1 uc.ctlplane.localhost uc.ctlplane'
|
'192.168.0.1 uc.ctlplane.localhost uc.ctlplane'
|
||||||
]
|
],
|
||||||
|
'CtlplaneNetworkAttributes': {},
|
||||||
}
|
}
|
||||||
|
|
||||||
testcase = self
|
testcase = self
|
||||||
|
@ -1119,6 +1131,8 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
|
||||||
object_client.put_container.assert_called_once_with(
|
object_client.put_container.assert_called_once_with(
|
||||||
'overcloud', headers={'x-container-meta-usage-tripleo': 'plan'})
|
'overcloud', headers={'x-container-meta-usage-tripleo': 'plan'})
|
||||||
|
|
||||||
|
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
|
||||||
|
'_get_ctlplane_attrs', autospec=True, return_value={})
|
||||||
@mock.patch('tripleoclient.utils.copy_clouds_yaml')
|
@mock.patch('tripleoclient.utils.copy_clouds_yaml')
|
||||||
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
|
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
|
||||||
'_get_undercloud_host_entry', autospec=True,
|
'_get_undercloud_host_entry', autospec=True,
|
||||||
|
@ -1145,7 +1159,8 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
|
||||||
mock_breakpoints_cleanup,
|
mock_breakpoints_cleanup,
|
||||||
mock_deploy_post_config,
|
mock_deploy_post_config,
|
||||||
mock_stack_network_check,
|
mock_stack_network_check,
|
||||||
mock_get_undercloud_host_entry, mock_copy):
|
mock_get_undercloud_host_entry, mock_copy,
|
||||||
|
mock_get_ctlplane_attrs):
|
||||||
fixture = deployment.DeploymentWorkflowFixture()
|
fixture = deployment.DeploymentWorkflowFixture()
|
||||||
self.useFixture(fixture)
|
self.useFixture(fixture)
|
||||||
plane_management_fixture = deployment.PlanManagementFixture()
|
plane_management_fixture = deployment.PlanManagementFixture()
|
||||||
|
@ -1204,7 +1219,8 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
|
||||||
'NtpServer': 'ntp',
|
'NtpServer': 'ntp',
|
||||||
'UndercloudHostsEntries': [
|
'UndercloudHostsEntries': [
|
||||||
'192.168.0.1 uc.ctlplane.localhost uc.ctlplane'
|
'192.168.0.1 uc.ctlplane.localhost uc.ctlplane'
|
||||||
]
|
],
|
||||||
|
'CtlplaneNetworkAttributes': {},
|
||||||
}
|
}
|
||||||
|
|
||||||
def _custom_create_params_env(_self, parameters, tht_root,
|
def _custom_create_params_env(_self, parameters, tht_root,
|
||||||
|
@ -1475,6 +1491,8 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
|
||||||
self.assertTrue(fixture.mock_config_download.called)
|
self.assertTrue(fixture.mock_config_download.called)
|
||||||
mock_copy.assert_called_once()
|
mock_copy.assert_called_once()
|
||||||
|
|
||||||
|
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
|
||||||
|
'_get_ctlplane_attrs', autospec=True, return_value={})
|
||||||
@mock.patch('tripleoclient.utils.copy_clouds_yaml')
|
@mock.patch('tripleoclient.utils.copy_clouds_yaml')
|
||||||
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
|
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
|
||||||
'_get_undercloud_host_entry', autospec=True,
|
'_get_undercloud_host_entry', autospec=True,
|
||||||
|
@ -1489,7 +1507,8 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
|
||||||
'create_plan_from_templates', autospec=True)
|
'create_plan_from_templates', autospec=True)
|
||||||
def test_config_download_timeout(
|
def test_config_download_timeout(
|
||||||
self, mock_plan_man, mock_hc, mock_stack_network_check, mock_hd,
|
self, mock_plan_man, mock_hc, mock_stack_network_check, mock_hd,
|
||||||
mock_overcloudrc, mock_get_undercloud_host_entry, mock_copy):
|
mock_overcloudrc, mock_get_undercloud_host_entry, mock_copy,
|
||||||
|
mock_get_ctlplane_attrs):
|
||||||
fixture = deployment.DeploymentWorkflowFixture()
|
fixture = deployment.DeploymentWorkflowFixture()
|
||||||
self.useFixture(fixture)
|
self.useFixture(fixture)
|
||||||
utils_fixture = deployment.UtilsOvercloudFixture()
|
utils_fixture = deployment.UtilsOvercloudFixture()
|
||||||
|
@ -1512,9 +1531,9 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
|
||||||
self.assertIn(
|
self.assertIn(
|
||||||
[mock.call(mock.ANY, mock.ANY, 'overcloud', mock.ANY,
|
[mock.call(mock.ANY, mock.ANY, 'overcloud', mock.ANY,
|
||||||
{'StackAction': 'UPDATE', 'UndercloudHostsEntries':
|
{'StackAction': 'UPDATE', 'UndercloudHostsEntries':
|
||||||
['192.168.0.1 uc.ctlplane.localhost uc.ctlplane']}, {},
|
['192.168.0.1 uc.ctlplane.localhost uc.ctlplane'],
|
||||||
451, mock.ANY, {}, False, False, False, None,
|
'CtlplaneNetworkAttributes': {}}, {}, 451, mock.ANY,
|
||||||
deployment_options={})],
|
{}, False, False, False, None, deployment_options={})],
|
||||||
mock_hd.mock_calls)
|
mock_hd.mock_calls)
|
||||||
self.assertIn(
|
self.assertIn(
|
||||||
[mock.call(mock.ANY, mock.ANY, mock.ANY, 'ctlplane', None, None,
|
[mock.call(mock.ANY, mock.ANY, mock.ANY, 'ctlplane', None, None,
|
||||||
|
@ -1757,6 +1776,67 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
|
||||||
'specified.')
|
'specified.')
|
||||||
mock_warning.assert_called_once_with(expected_message)
|
mock_warning.assert_called_once_with(expected_message)
|
||||||
|
|
||||||
|
@mock.patch('openstack.connect', autospec=True)
|
||||||
|
def test__get_ctlplane_attrs_no_config(self, mock_connect):
|
||||||
|
mock_connect.side_effect = openstack.exceptions.ConfigException
|
||||||
|
function = overcloud_deploy.DeployOvercloud._get_ctlplane_attrs
|
||||||
|
|
||||||
|
expected = dict()
|
||||||
|
self.assertEqual(expected, function(mock.ANY))
|
||||||
|
|
||||||
|
@mock.patch('openstack.connect', autospec=True)
|
||||||
|
@mock.patch.object(openstack.connection, 'Connection', autospec=True)
|
||||||
|
def test__get_ctlplane_attrs_no_network(self, mock_conn, mock_connect):
|
||||||
|
mock_connect.return_value = mock_conn
|
||||||
|
function = overcloud_deploy.DeployOvercloud._get_ctlplane_attrs
|
||||||
|
|
||||||
|
mock_conn.network.find_network.return_value = None
|
||||||
|
expected = dict()
|
||||||
|
self.assertEqual(expected, function(mock.ANY))
|
||||||
|
|
||||||
|
@mock.patch('openstack.connect', autospec=True)
|
||||||
|
@mock.patch.object(openstack.connection, 'Connection', autospec=True)
|
||||||
|
def test__get_ctlplane_attrs(self, mock_conn, mock_connect):
|
||||||
|
mock_connect.return_value = mock_conn
|
||||||
|
function = overcloud_deploy.DeployOvercloud._get_ctlplane_attrs
|
||||||
|
|
||||||
|
fake_network = fakes.FakeNeutronNetwork(
|
||||||
|
name='net_name',
|
||||||
|
mtu=1440,
|
||||||
|
dns_domain='ctlplane.localdomain.',
|
||||||
|
tags=[],
|
||||||
|
subnet_ids=['subnet_id'])
|
||||||
|
fake_subnet = fakes.FakeNeutronSubnet(
|
||||||
|
id='subnet_id',
|
||||||
|
name='subnet_name',
|
||||||
|
cidr='192.168.24.0/24',
|
||||||
|
gateway_ip='192.168.24.1',
|
||||||
|
host_routes=[
|
||||||
|
{'destination': '192.168.25.0/24', 'nexthop': '192.168.24.1'}],
|
||||||
|
dns_nameservers=['192.168.24.254'],
|
||||||
|
ip_version=4
|
||||||
|
)
|
||||||
|
mock_conn.network.find_network.return_value = fake_network
|
||||||
|
mock_conn.network.get_subnet.return_value = fake_subnet
|
||||||
|
expected = {
|
||||||
|
'network': {
|
||||||
|
'dns_domain': 'ctlplane.localdomain.',
|
||||||
|
'mtu': 1440,
|
||||||
|
'name': 'net_name',
|
||||||
|
'tags': []},
|
||||||
|
'subnets': {
|
||||||
|
'subnet_name': {
|
||||||
|
'cidr': '192.168.24.0/24',
|
||||||
|
'dns_nameservers': ['192.168.24.254'],
|
||||||
|
'gateway_ip': '192.168.24.1',
|
||||||
|
'host_routes': [{'destination': '192.168.25.0/24',
|
||||||
|
'nexthop': '192.168.24.1'}],
|
||||||
|
'ip_version': 4,
|
||||||
|
'name': 'subnet_name'}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.assertEqual(expected, function(mock.ANY))
|
||||||
|
|
||||||
|
|
||||||
class TestArgumentValidation(fakes.TestDeployOvercloud):
|
class TestArgumentValidation(fakes.TestDeployOvercloud):
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,8 @@ class TestOvercloudUpdatePrepare(fakes.TestOvercloudUpdatePrepare):
|
||||||
self.mock_uuid4 = uuid4_patcher.start()
|
self.mock_uuid4 = uuid4_patcher.start()
|
||||||
self.addCleanup(self.mock_uuid4.stop)
|
self.addCleanup(self.mock_uuid4.stop)
|
||||||
|
|
||||||
|
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
|
||||||
|
'_get_ctlplane_attrs', autospec=True, return_value={})
|
||||||
@mock.patch('tripleoclient.utils.ensure_run_as_normal_user')
|
@mock.patch('tripleoclient.utils.ensure_run_as_normal_user')
|
||||||
@mock.patch('tripleoclient.utils.prompt_user_for_confirmation',
|
@mock.patch('tripleoclient.utils.prompt_user_for_confirmation',
|
||||||
return_value=True)
|
return_value=True)
|
||||||
|
@ -57,7 +59,7 @@ class TestOvercloudUpdatePrepare(fakes.TestOvercloudUpdatePrepare):
|
||||||
def test_update_out(self, mock_deploy, mock_open, mock_copy, mock_yaml,
|
def test_update_out(self, mock_deploy, mock_open, mock_copy, mock_yaml,
|
||||||
mock_abspath, mock_update, mock_logger,
|
mock_abspath, mock_update, mock_logger,
|
||||||
mock_get_stack, mock_get_undercloud_host_entry,
|
mock_get_stack, mock_get_undercloud_host_entry,
|
||||||
mock_confirm, mock_usercheck):
|
mock_confirm, mock_usercheck, mock_get_ctlplane_attrs):
|
||||||
mock_stack = mock.Mock(parameters={'DeployIdentifier': ''})
|
mock_stack = mock.Mock(parameters={'DeployIdentifier': ''})
|
||||||
mock_stack.stack_name = 'overcloud'
|
mock_stack.stack_name = 'overcloud'
|
||||||
mock_get_stack.return_value = mock_stack
|
mock_get_stack.return_value = mock_stack
|
||||||
|
|
|
@ -923,6 +923,32 @@ class TestNetworkSettings(TestBaseNetworkSettings):
|
||||||
self.assertRaises(exceptions.DeploymentError,
|
self.assertRaises(exceptions.DeploymentError,
|
||||||
undercloud_config._generate_inspection_subnets)
|
undercloud_config._generate_inspection_subnets)
|
||||||
|
|
||||||
|
def test__env_set_undercloud_ctlplane_networks_attribues(self):
|
||||||
|
self.conf.config(local_subnet='ctlplane-subnet',
|
||||||
|
local_mtu=1444,
|
||||||
|
undercloud_nameservers=['192.168.24.253',
|
||||||
|
'192.168.24.252'])
|
||||||
|
self.conf.config(cidr='192.168.24.0/24',
|
||||||
|
gateway='192.168.24.254',
|
||||||
|
host_routes=[{'destination': '10.10.10.254/32',
|
||||||
|
'nexthop': '192.168.24.1'}],
|
||||||
|
group='ctlplane-subnet')
|
||||||
|
env = {}
|
||||||
|
undercloud_config._env_set_undercloud_ctlplane_networks_attribues(env)
|
||||||
|
expected = {
|
||||||
|
'CtlplaneNetworkAttributes': {
|
||||||
|
'network': {'mtu': 1444},
|
||||||
|
'subnets': {
|
||||||
|
'ctlplane-subnet': {
|
||||||
|
'cidr': '192.168.24.0/24',
|
||||||
|
'dns_nameservers': ['192.168.24.253',
|
||||||
|
'192.168.24.252'],
|
||||||
|
'gateway_ip': '192.168.24.254',
|
||||||
|
'host_routes': [{'destination': '10.10.10.254/32',
|
||||||
|
'nexthop': '192.168.24.1'}],
|
||||||
|
'tags': []}}}}
|
||||||
|
self.assertEqual(expected, env)
|
||||||
|
|
||||||
|
|
||||||
class TestChronySettings(TestBaseNetworkSettings):
|
class TestChronySettings(TestBaseNetworkSettings):
|
||||||
def test_default(self):
|
def test_default(self):
|
||||||
|
|
|
@ -29,6 +29,7 @@ import time
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
from heatclient.common import template_utils
|
from heatclient.common import template_utils
|
||||||
|
import openstack
|
||||||
from osc_lib import exceptions as oscexc
|
from osc_lib import exceptions as oscexc
|
||||||
from osc_lib.i18n import _
|
from osc_lib.i18n import _
|
||||||
from swiftclient.exceptions import ClientException
|
from swiftclient.exceptions import ClientException
|
||||||
|
@ -100,8 +101,44 @@ class DeployOvercloud(command.Command):
|
||||||
parameters[
|
parameters[
|
||||||
'UndercloudHostsEntries'] = [self._get_undercloud_host_entry()]
|
'UndercloudHostsEntries'] = [self._get_undercloud_host_entry()]
|
||||||
|
|
||||||
|
parameters['CtlplaneNetworkAttributes'] = self._get_ctlplane_attrs()
|
||||||
|
|
||||||
return parameters
|
return parameters
|
||||||
|
|
||||||
|
def _get_ctlplane_attrs(self):
|
||||||
|
try:
|
||||||
|
conn = openstack.connect('undercloud')
|
||||||
|
except openstack.exceptions.ConfigException:
|
||||||
|
return dict()
|
||||||
|
|
||||||
|
network = conn.network.find_network('ctlplane')
|
||||||
|
if network is None:
|
||||||
|
return dict()
|
||||||
|
|
||||||
|
net_attributes_map = {'network': dict(), 'subnets': dict()}
|
||||||
|
|
||||||
|
net_attributes_map['network'].update({
|
||||||
|
'name': network.name,
|
||||||
|
'mtu': network.mtu,
|
||||||
|
'dns_domain': network.dns_domain,
|
||||||
|
'tags': network.tags,
|
||||||
|
})
|
||||||
|
|
||||||
|
for subnet_id in network.subnet_ids:
|
||||||
|
subnet = conn.network.get_subnet(subnet_id)
|
||||||
|
net_attributes_map['subnets'].update({
|
||||||
|
subnet.name: {
|
||||||
|
'name': subnet.name,
|
||||||
|
'cidr': subnet.cidr,
|
||||||
|
'gateway_ip': subnet.gateway_ip,
|
||||||
|
'host_routes': subnet.host_routes,
|
||||||
|
'dns_nameservers': subnet.dns_nameservers,
|
||||||
|
'ip_version': subnet.ip_version,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return net_attributes_map
|
||||||
|
|
||||||
def _cleanup_host_entry(self, entry):
|
def _cleanup_host_entry(self, entry):
|
||||||
# remove any tab or space excess
|
# remove any tab or space excess
|
||||||
entry_stripped = re.sub('[ \t]+', ' ', str(entry).rstrip())
|
entry_stripped = re.sub('[ \t]+', ' ', str(entry).rstrip())
|
||||||
|
|
|
@ -703,6 +703,18 @@ class Deploy(command.Command):
|
||||||
stack_name=parsed_args.stack,
|
stack_name=parsed_args.stack,
|
||||||
role_name=self._get_primary_role_name(
|
role_name=self._get_primary_role_name(
|
||||||
roles_file_path, parsed_args.templates)))
|
roles_file_path, parsed_args.templates)))
|
||||||
|
tmp_env.update(
|
||||||
|
{
|
||||||
|
'CtlplaneNetworkAttributes': {
|
||||||
|
'subnets': {
|
||||||
|
'ctlplane-subnet': {
|
||||||
|
'cidr': str(ip_nw.cidr),
|
||||||
|
'host_routes': []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
with open(maps_file, 'w') as env_file:
|
with open(maps_file, 'w') as env_file:
|
||||||
yaml.safe_dump({'parameter_defaults': tmp_env}, env_file,
|
yaml.safe_dump({'parameter_defaults': tmp_env}, env_file,
|
||||||
|
|
|
@ -414,6 +414,18 @@ def _process_network_args(env):
|
||||||
raise exceptions.InvalidConfiguration(msg)
|
raise exceptions.InvalidConfiguration(msg)
|
||||||
|
|
||||||
|
|
||||||
|
def _env_set_undercloud_ctlplane_networks_attribues(env):
|
||||||
|
env['CtlplaneNetworkAttributes'] = dict(network=dict(), subnets=dict())
|
||||||
|
env['CtlplaneNetworkAttributes']['network']['mtu'] = CONF.local_mtu
|
||||||
|
env['CtlplaneNetworkAttributes']['subnets']['ctlplane-subnet'] = {
|
||||||
|
'cidr': CONF.get(CONF.local_subnet).cidr,
|
||||||
|
'gateway_ip': CONF.get(CONF.local_subnet).gateway,
|
||||||
|
'dns_nameservers': CONF.undercloud_nameservers,
|
||||||
|
'host_routes': CONF.get(CONF.local_subnet).host_routes,
|
||||||
|
'tags': [],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def _process_chrony_acls(env):
|
def _process_chrony_acls(env):
|
||||||
"""Populate ACL rules for chrony to allow ctlplane subnets"""
|
"""Populate ACL rules for chrony to allow ctlplane subnets"""
|
||||||
acl_rules = []
|
acl_rules = []
|
||||||
|
@ -468,6 +480,7 @@ def prepare_undercloud_deploy(upgrade=False, no_validations=True,
|
||||||
|
|
||||||
# Set up parameters for undercloud networking
|
# Set up parameters for undercloud networking
|
||||||
_process_network_args(env_data)
|
_process_network_args(env_data)
|
||||||
|
_env_set_undercloud_ctlplane_networks_attribues(env_data)
|
||||||
|
|
||||||
# Setup parameter for Chrony ACL rules
|
# Setup parameter for Chrony ACL rules
|
||||||
_process_chrony_acls(env_data)
|
_process_chrony_acls(env_data)
|
||||||
|
|
Loading…
Reference in New Issue