Merge "Move get_ctlplane_attrs to utils"

This commit is contained in:
Zuul 2021-06-10 19:28:14 +00:00 committed by Gerrit Code Review
commit 5f358350fb
7 changed files with 219 additions and 220 deletions

View File

@ -330,3 +330,84 @@ class FakePlaybookExecution(utils.TestCommand):
def fake_ansible_runner_run_return(rc=0):
return 'Test Status', rc
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)

View File

@ -19,6 +19,7 @@ import argparse
import datetime
import logging
import mock
import openstack
import os
import os.path
import shutil
@ -1911,3 +1912,62 @@ class TestTempDirs(base.TestCase):
mock_log.assert_called_once_with(
"Not cleaning temporary directory [ foo ]")
class TestGetCtlplaneAttrs(base.TestCase):
@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
mock_conn.network.find_network.return_value = None
expected = dict()
self.assertEqual(expected, utils.get_ctlplane_attrs())
@mock.patch('openstack.connect', autospec=True)
def test_get_ctlplane_attrs_no_config(self, mock_connect):
mock_connect.side_effect = openstack.exceptions.ConfigException
expected = dict()
self.assertEqual(expected, utils.get_ctlplane_attrs())
@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
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, utils.get_ctlplane_attrs())

View File

@ -108,84 +108,3 @@ class TestDeployOvercloud(fakes.FakePlaybookExecution):
def setUp(self):
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)

View File

@ -21,7 +21,6 @@ import tempfile
import yaml
import mock
import openstack
from osc_lib import exceptions as oscexc
from osc_lib.tests import utils
@ -129,8 +128,8 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
@mock.patch('heatclient.common.template_utils.'
'process_environment_and_files', autospec=True)
@mock.patch('tripleoclient.utils.check_nic_config_with_ansible')
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
'_get_ctlplane_attrs', autospec=True, return_value={})
@mock.patch('tripleoclient.utils.get_ctlplane_attrs', autospec=True,
return_value={})
@mock.patch('tripleoclient.utils.copy_clouds_yaml')
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
'_get_undercloud_host_entry', autospec=True,
@ -247,8 +246,8 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
autospec=True, return_value={})
@mock.patch('heatclient.common.template_utils.'
'process_environment_and_files', autospec=True)
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
'_get_ctlplane_attrs', autospec=True, return_value={})
@mock.patch('tripleoclient.utils.get_ctlplane_attrs', autospec=True,
return_value={})
@mock.patch('tripleoclient.workflows.deployment.create_overcloudrc',
autospec=True)
@mock.patch('tripleoclient.utils.copy_clouds_yaml')
@ -864,8 +863,8 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
return_value={})
@mock.patch('tripleoclient.workflows.roles.get_roles_data',
autospec=True, return_value={})
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
'_get_ctlplane_attrs', autospec=True, return_value={})
@mock.patch('tripleoclient.utils.get_ctlplane_attrs', autospec=True,
return_value={})
@mock.patch('tripleoclient.utils.copy_clouds_yaml')
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
'_get_undercloud_host_entry', autospec=True,
@ -1246,8 +1245,8 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
@mock.patch('tripleoclient.utils.process_multiple_environments',
autospec=True)
@mock.patch('tripleoclient.utils.check_nic_config_with_ansible')
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
'_get_ctlplane_attrs', autospec=True, return_value={})
@mock.patch('tripleoclient.utils.get_ctlplane_attrs', autospec=True,
return_value={})
@mock.patch('tripleoclient.utils.copy_clouds_yaml')
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
'_get_undercloud_host_entry', autospec=True,
@ -1543,67 +1542,6 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
'specified.')
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):

View File

@ -36,8 +36,37 @@ class TestOvercloudUpdatePrepare(fakes.TestOvercloudUpdatePrepare):
self.mock_uuid4 = uuid4_patcher.start()
self.addCleanup(self.mock_uuid4.stop)
@mock.patch('tripleoclient.utils.ensure_run_as_normal_user')
@mock.patch('tripleoclient.utils.prompt_user_for_confirmation',
return_value=True)
@mock.patch('six.moves.builtins.open')
@mock.patch('os.path.abspath')
@mock.patch('yaml.safe_load')
@mock.patch('shutil.copytree', autospec=True)
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
'_get_ctlplane_attrs', autospec=True, return_value={})
'take_action', autospec=True)
def test_update_failed(self, mock_deploy, mock_copy, mock_yaml,
mock_abspath, mock_open,
mock_confirm, mock_usercheck):
mock_deploy.side_effect = exceptions.DeploymentError()
mock_yaml.return_value = {'fake_container': 'fake_value'}
argslist = ['--stack', 'overcloud', '--templates', ]
verifylist = [
('stack', 'overcloud'),
('templates', constants.TRIPLEO_HEAT_TEMPLATES),
]
parsed_args = self.check_parser(self.cmd, argslist, verifylist)
with mock.patch('os.path.exists') as mock_exists, \
mock.patch('os.path.isfile') as mock_isfile:
mock_exists.return_value = True
mock_isfile.return_value = True
self.assertRaises(exceptions.DeploymentError,
self.cmd.take_action, parsed_args)
mock_usercheck.assert_called_once()
@mock.patch('tripleoclient.utils.get_ctlplane_attrs', autospec=True,
return_value={})
@mock.patch('tripleoclient.utils.ensure_run_as_normal_user')
@mock.patch('tripleoclient.utils.prompt_user_for_confirmation',
return_value=True)
@ -75,35 +104,6 @@ class TestOvercloudUpdatePrepare(fakes.TestOvercloudUpdatePrepare):
mock_usercheck.assert_called_once()
mock_deploy.assert_called_once()
@mock.patch('tripleoclient.utils.ensure_run_as_normal_user')
@mock.patch('tripleoclient.utils.prompt_user_for_confirmation',
return_value=True)
@mock.patch('six.moves.builtins.open')
@mock.patch('os.path.abspath')
@mock.patch('yaml.safe_load')
@mock.patch('shutil.copytree', autospec=True)
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
'take_action', autospec=True)
def test_update_failed(self, mock_deploy, mock_copy, mock_yaml,
mock_abspath, mock_open,
mock_confirm, mock_usercheck):
mock_deploy.side_effect = exceptions.DeploymentError()
mock_yaml.return_value = {'fake_container': 'fake_value'}
argslist = ['--stack', 'overcloud', '--templates', ]
verifylist = [
('stack', 'overcloud'),
('templates', constants.TRIPLEO_HEAT_TEMPLATES),
]
parsed_args = self.check_parser(self.cmd, argslist, verifylist)
with mock.patch('os.path.exists') as mock_exists, \
mock.patch('os.path.isfile') as mock_isfile:
mock_exists.return_value = True
mock_isfile.return_value = True
self.assertRaises(exceptions.DeploymentError,
self.cmd.take_action, parsed_args)
mock_usercheck.assert_called_once()
class TestOvercloudUpdateRun(fakes.TestOvercloudUpdateRun):

View File

@ -30,6 +30,7 @@ import logging
import multiprocessing
import netaddr
import openstack
import os
import os.path
import pwd
@ -2675,3 +2676,41 @@ def export_overcloud(heat, stack, excludes, should_filter,
data.update({'AddVipsToEtcHosts': False})
data = dict(parameter_defaults=data)
return data
def get_ctlplane_attrs():
try:
conn = openstack.connect('undercloud')
except openstack.exceptions.ConfigException:
return dict()
if not conn.endpoint_for('network'):
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

View File

@ -31,7 +31,6 @@ import yaml
from heatclient.common import template_utils
from keystoneauth1.exceptions.catalog import EndpointNotFound
import openstack
from osc_lib import exceptions as oscexc
from osc_lib.i18n import _
from tripleo_common.image import kolla_builder
@ -124,47 +123,10 @@ class DeployOvercloud(command.Command):
parameters[
'UndercloudHostsEntries'] = [self._get_undercloud_host_entry()]
parameters['CtlplaneNetworkAttributes'] = self._get_ctlplane_attrs()
parameters['CtlplaneNetworkAttributes'] = utils.get_ctlplane_attrs()
return parameters
def _get_ctlplane_attrs(self):
try:
conn = openstack.connect('undercloud')
except openstack.exceptions.ConfigException:
return dict()
if not conn.endpoint_for('network'):
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):
# remove any tab or space excess
entry_stripped = re.sub('[ \t]+', ' ', str(entry).rstrip())