862 lines
30 KiB
Python
862 lines
30 KiB
Python
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
# implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
from unittest import mock
|
|
|
|
import yaml
|
|
|
|
from swiftclient import exceptions as swiftexceptions
|
|
from ironicclient import exceptions as ironicexceptions
|
|
|
|
from tripleo_common import constants
|
|
from tripleo_common.tests import base
|
|
from tripleo_common.utils import stack_parameters
|
|
from tripleo_common.utils import nodes
|
|
|
|
|
|
class StackParametersTest(base.TestCase):
|
|
|
|
@mock.patch('tripleo_common.utils.plan.'
|
|
'cache_delete')
|
|
def test_reset_parameter(self, mock_cache):
|
|
swift = mock.MagicMock(url="http://test.com")
|
|
mock_env = yaml.safe_dump({
|
|
'name': constants.DEFAULT_CONTAINER_NAME,
|
|
'template': 'template',
|
|
'environments': [{u'path': u'environments/test.yaml'}],
|
|
'parameter_defaults': {'SomeTestParameter': 42}
|
|
}, default_flow_style=False)
|
|
swift.get_object.return_value = ({}, mock_env)
|
|
|
|
# Test
|
|
stack_parameters.reset_parameters(swift)
|
|
|
|
mock_env_reset = yaml.safe_dump({
|
|
'name': constants.DEFAULT_CONTAINER_NAME,
|
|
'template': 'template',
|
|
'environments': [{u'path': u'environments/test.yaml'}]
|
|
}, default_flow_style=False)
|
|
|
|
swift.put_object.assert_called_once_with(
|
|
constants.DEFAULT_CONTAINER_NAME,
|
|
constants.PLAN_ENVIRONMENT,
|
|
mock_env_reset
|
|
)
|
|
mock_cache.assert_called_once_with(
|
|
swift,
|
|
"overcloud",
|
|
"tripleo.parameters.get"
|
|
)
|
|
|
|
@mock.patch('uuid.uuid4')
|
|
@mock.patch('heatclient.common.template_utils.'
|
|
'process_multiple_environments_and_files')
|
|
@mock.patch('heatclient.common.template_utils.'
|
|
'get_template_contents')
|
|
@mock.patch('tripleo_common.utils.plan.'
|
|
'cache_set')
|
|
def test_update_parameters(self, mock_cache,
|
|
mock_get_template_contents,
|
|
mock_env_files,
|
|
mock_uuid):
|
|
|
|
mock_env_files.return_value = ({}, {})
|
|
|
|
swift = mock.MagicMock(url="http://test.com")
|
|
|
|
mock_env = yaml.safe_dump({
|
|
'name': constants.DEFAULT_CONTAINER_NAME,
|
|
'temp_environment': 'temp_environment',
|
|
'template': 'template',
|
|
'environments': [{u'path': u'environments/test.yaml'}],
|
|
}, default_flow_style=False)
|
|
|
|
mock_roles = yaml.safe_dump([{"name": "foo"}])
|
|
mock_network = yaml.safe_dump([{'enabled': False}])
|
|
mock_exclude = yaml.safe_dump({"name": "foo"})
|
|
|
|
swift.get_object.side_effect = (
|
|
({}, mock_env),
|
|
({}, mock_env),
|
|
({}, mock_roles),
|
|
({}, mock_network),
|
|
({}, mock_exclude),
|
|
({}, mock_env),
|
|
({}, mock_env),
|
|
({}, mock_env),
|
|
({}, mock_roles),
|
|
({}, mock_network),
|
|
({}, mock_exclude),
|
|
({}, mock_env),
|
|
({}, mock_env),
|
|
swiftexceptions.ClientException('atest2')
|
|
)
|
|
|
|
def return_container_files(*args):
|
|
return ('headers', [{'name': 'foo.role.j2.yaml'}])
|
|
|
|
swift.get_container = mock.MagicMock(
|
|
side_effect=return_container_files)
|
|
|
|
mock_heat = mock.MagicMock()
|
|
|
|
mock_heat.stacks.validate.return_value = {
|
|
"Type": "Foo",
|
|
"Description": "Le foo bar",
|
|
"Parameters": {"bar": {"foo": "bar barz"}},
|
|
"NestedParameters": {"Type": "foobar"}
|
|
}
|
|
|
|
mock_uuid.return_value = "cheese"
|
|
|
|
expected_value = {
|
|
'environment_parameters': None,
|
|
'heat_resource_tree': {
|
|
'parameters': {'bar': {'foo': 'bar barz',
|
|
'name': 'bar'}},
|
|
'resources': {'cheese': {
|
|
'id': 'cheese',
|
|
'name': 'Root',
|
|
'description': 'Le foo bar',
|
|
'parameters': ['bar'],
|
|
'resources': ['cheese'],
|
|
'type': 'Foo'}
|
|
}
|
|
}
|
|
}
|
|
|
|
mock_get_template_contents.return_value = ({}, {
|
|
'heat_template_version': '2016-04-30'
|
|
})
|
|
|
|
# Test
|
|
test_parameters = {'SomeTestParameter': 42}
|
|
result = stack_parameters.update_parameters(
|
|
swift, mock_heat, test_parameters)
|
|
|
|
mock_env_updated = yaml.safe_dump({
|
|
'name': constants.DEFAULT_CONTAINER_NAME,
|
|
'temp_environment': 'temp_environment',
|
|
'parameter_defaults': {'SomeTestParameter': 42},
|
|
'template': 'template',
|
|
'environments': [{u'path': u'environments/test.yaml'}]
|
|
}, default_flow_style=False)
|
|
|
|
swift.put_object.assert_any_call(
|
|
constants.DEFAULT_CONTAINER_NAME,
|
|
constants.PLAN_ENVIRONMENT,
|
|
mock_env_updated
|
|
)
|
|
|
|
mock_heat.stacks.validate.assert_called_once_with(
|
|
environment={},
|
|
files={},
|
|
show_nested=True,
|
|
template={'heat_template_version': '2016-04-30'},
|
|
)
|
|
|
|
mock_cache.assert_called_once_with(
|
|
swift,
|
|
"overcloud",
|
|
"tripleo.parameters.get",
|
|
expected_value
|
|
)
|
|
self.assertEqual(result, expected_value)
|
|
|
|
@mock.patch('heatclient.common.template_utils.'
|
|
'process_multiple_environments_and_files')
|
|
@mock.patch('heatclient.common.template_utils.'
|
|
'get_template_contents')
|
|
@mock.patch('tripleo_common.utils.plan.'
|
|
'cache_set')
|
|
def test_update_parameter_new_key(self, mock_cache,
|
|
mock_get_template_contents,
|
|
mock_env_files):
|
|
|
|
mock_env_files.return_value = ({}, {})
|
|
|
|
swift = mock.MagicMock(url="http://test.com")
|
|
mock_env = yaml.safe_dump({
|
|
'name': constants.DEFAULT_CONTAINER_NAME,
|
|
'temp_environment': 'temp_environment',
|
|
'template': 'template',
|
|
'environments': [{u'path': u'environments/test.yaml'}],
|
|
}, default_flow_style=False)
|
|
|
|
mock_roles = yaml.safe_dump([{"name": "foo"}])
|
|
mock_network = yaml.safe_dump([{'enabled': False}])
|
|
mock_exclude = yaml.safe_dump({"name": "foo"})
|
|
|
|
swift.get_object.side_effect = (
|
|
({}, mock_env),
|
|
({}, mock_env),
|
|
({}, mock_roles),
|
|
({}, mock_network),
|
|
({}, mock_exclude),
|
|
({}, mock_env),
|
|
({}, mock_env),
|
|
({}, mock_env),
|
|
({}, mock_roles),
|
|
({}, mock_network),
|
|
({}, mock_exclude),
|
|
({}, mock_env),
|
|
({}, mock_env),
|
|
swiftexceptions.ClientException('atest2')
|
|
)
|
|
|
|
def return_container_files(*args):
|
|
return ('headers', [{'name': 'foo.role.j2.yaml'}])
|
|
|
|
swift.get_container = mock.MagicMock(
|
|
side_effect=return_container_files)
|
|
|
|
heat = mock.MagicMock()
|
|
heat.stacks.validate.return_value = {}
|
|
|
|
mock_get_template_contents.return_value = ({}, {
|
|
'heat_template_version': '2016-04-30'
|
|
})
|
|
|
|
# Test
|
|
test_parameters = {'SomeTestParameter': 42}
|
|
stack_parameters.update_parameters(
|
|
swift, heat, test_parameters,
|
|
parameter_key='test_key')
|
|
mock_env_updated = yaml.safe_dump({
|
|
'name': constants.DEFAULT_CONTAINER_NAME,
|
|
'temp_environment': 'temp_environment',
|
|
'test_key': {'SomeTestParameter': 42},
|
|
'template': 'template',
|
|
'environments': [{u'path': u'environments/test.yaml'}]
|
|
}, default_flow_style=False)
|
|
|
|
swift.put_object.assert_any_call(
|
|
constants.DEFAULT_CONTAINER_NAME,
|
|
constants.PLAN_ENVIRONMENT,
|
|
mock_env_updated
|
|
)
|
|
|
|
heat.stacks.validate.assert_called_once_with(
|
|
environment={},
|
|
files={},
|
|
show_nested=True,
|
|
template={'heat_template_version': '2016-04-30'},
|
|
)
|
|
|
|
mock_cache.assert_called_once_with(
|
|
swift,
|
|
"overcloud",
|
|
"tripleo.parameters.get",
|
|
{'environment_parameters': None, 'heat_resource_tree': {}}
|
|
)
|
|
|
|
@mock.patch('heatclient.common.template_utils.'
|
|
'process_multiple_environments_and_files')
|
|
@mock.patch('heatclient.common.template_utils.'
|
|
'get_template_contents')
|
|
@mock.patch('tripleo_common.utils.plan.'
|
|
'cache_set')
|
|
@mock.patch('tripleo_common.utils.parameters.set_count_and_flavor_params')
|
|
def test_update_role_parameter(self, mock_set_count_and_flavor,
|
|
mock_cache, mock_get_template_contents,
|
|
mock_env_files):
|
|
|
|
mock_env_files.return_value = ({}, {})
|
|
|
|
swift = mock.MagicMock(url="http://test.com")
|
|
mock_env = yaml.safe_dump({
|
|
'name': 'overcast'
|
|
}, default_flow_style=False)
|
|
|
|
mock_roles = yaml.safe_dump([{"name": "foo"}])
|
|
mock_network = yaml.safe_dump([{'enabled': False}])
|
|
mock_exclude = yaml.safe_dump({"name": "foo"})
|
|
|
|
swift.get_object.side_effect = (
|
|
({}, mock_env),
|
|
({}, mock_env),
|
|
({}, mock_roles),
|
|
({}, mock_network),
|
|
({}, mock_exclude),
|
|
({}, mock_env),
|
|
({}, mock_env),
|
|
({}, mock_env),
|
|
({}, mock_roles),
|
|
({}, mock_network),
|
|
({}, mock_exclude),
|
|
({}, mock_env),
|
|
({}, mock_env),
|
|
swiftexceptions.ClientException('atest2')
|
|
)
|
|
|
|
def return_container_files(*args):
|
|
return ('headers', [{'name': 'foo.yaml'}])
|
|
|
|
swift.get_container = mock.MagicMock(
|
|
side_effect=return_container_files)
|
|
|
|
heat = mock.MagicMock()
|
|
ironic = mock.MagicMock()
|
|
compute = mock.MagicMock()
|
|
|
|
heat.stacks.validate.return_value = {}
|
|
|
|
mock_get_template_contents.return_value = ({}, {
|
|
'heat_template_version': '2016-04-30'
|
|
})
|
|
|
|
params = {'CephStorageCount': 1,
|
|
'OvercloudCephStorageFlavor': 'ceph-storage'}
|
|
mock_set_count_and_flavor.return_value = params
|
|
|
|
stack_parameters.update_role_parameters(
|
|
swift, heat, ironic, compute,
|
|
'ceph-storage', 'overcast')
|
|
mock_env_updated = yaml.safe_dump({
|
|
'name': 'overcast',
|
|
'parameter_defaults': params
|
|
}, default_flow_style=False)
|
|
|
|
swift.put_object.assert_any_call(
|
|
'overcast',
|
|
constants.PLAN_ENVIRONMENT,
|
|
mock_env_updated
|
|
)
|
|
|
|
heat.stacks.validate.assert_called_once_with(
|
|
environment={},
|
|
files={},
|
|
show_nested=True,
|
|
template={'heat_template_version': '2016-04-30'},
|
|
)
|
|
|
|
mock_cache.assert_called_once_with(
|
|
swift,
|
|
"overcast",
|
|
"tripleo.parameters.get",
|
|
{'environment_parameters': None, 'heat_resource_tree': {}}
|
|
)
|
|
|
|
@mock.patch('tripleo_common.utils.plan.'
|
|
'cache_set')
|
|
@mock.patch('tripleo_common.utils.plan.'
|
|
'cache_get')
|
|
@mock.patch('heatclient.common.template_utils.'
|
|
'process_multiple_environments_and_files')
|
|
@mock.patch('heatclient.common.template_utils.get_template_contents')
|
|
def test_empty_resource_tree(self,
|
|
mock_get_template_contents,
|
|
mock_process_multiple_environments_and_files,
|
|
mock_cache_get,
|
|
mock_cache_set):
|
|
|
|
mock_cache_get.return_value = None
|
|
swift = mock.MagicMock(url="http://test.com")
|
|
mock_env = yaml.safe_dump({
|
|
'temp_environment': 'temp_environment',
|
|
'template': 'template',
|
|
'environments': [{u'path': u'environments/test.yaml'}]
|
|
}, default_flow_style=False)
|
|
swift.get_object.side_effect = (
|
|
({}, mock_env),
|
|
swiftexceptions.ClientException('atest2'),
|
|
({}, mock_env)
|
|
)
|
|
mock_get_template_contents.return_value = ({}, {
|
|
'heat_template_version': '2016-04-30'
|
|
})
|
|
mock_process_multiple_environments_and_files.return_value = ({}, {})
|
|
|
|
mock_heat = mock.MagicMock()
|
|
mock_heat.stacks.validate.return_value = {}
|
|
|
|
expected_value = {
|
|
'heat_resource_tree': {},
|
|
'environment_parameters': None,
|
|
}
|
|
|
|
# Test
|
|
result = stack_parameters.get_flattened_parameters(swift, mock_heat)
|
|
mock_heat.stacks.validate.assert_called_once_with(
|
|
environment={},
|
|
files={},
|
|
show_nested=True,
|
|
template={'heat_template_version': '2016-04-30'},
|
|
)
|
|
self.assertEqual(result, expected_value)
|
|
|
|
@mock.patch('tripleo_common.utils.plan.'
|
|
'cache_set')
|
|
@mock.patch('tripleo_common.utils.plan.'
|
|
'cache_get')
|
|
@mock.patch('uuid.uuid4', side_effect=['1', '2'])
|
|
@mock.patch('heatclient.common.template_utils.'
|
|
'process_multiple_environments_and_files')
|
|
@mock.patch('heatclient.common.template_utils.get_template_contents')
|
|
def test_valid_resource_tree(self,
|
|
mock_get_template_contents,
|
|
mock_process_multiple_environments_and_files,
|
|
mock_uuid,
|
|
mock_cache_get,
|
|
mock_cache_set):
|
|
|
|
mock_cache_get.return_value = None
|
|
swift = mock.MagicMock(url="http://test.com")
|
|
mock_env = yaml.safe_dump({
|
|
'temp_environment': 'temp_environment',
|
|
'template': 'template',
|
|
'environments': [{u'path': u'environments/test.yaml'}]
|
|
}, default_flow_style=False)
|
|
swift.get_object.side_effect = (
|
|
({}, mock_env),
|
|
swiftexceptions.ClientException('atest2'),
|
|
({}, mock_env)
|
|
)
|
|
mock_get_template_contents.return_value = ({}, {
|
|
'heat_template_version': '2016-04-30'
|
|
})
|
|
mock_process_multiple_environments_and_files.return_value = ({}, {})
|
|
|
|
mock_heat = mock.MagicMock()
|
|
mock_heat.stacks.validate.return_value = {
|
|
'NestedParameters': {
|
|
'CephStorageHostsDeployment': {
|
|
'Type': 'OS::Heat::StructuredDeployments',
|
|
},
|
|
},
|
|
'description': 'sample',
|
|
'Parameters': {
|
|
'ControllerCount': {
|
|
'Default': 1,
|
|
'Type': 'Number',
|
|
},
|
|
}
|
|
}
|
|
|
|
expected_value = {
|
|
'heat_resource_tree': {
|
|
'resources': {
|
|
'1': {
|
|
'id': '1',
|
|
'name': 'Root',
|
|
'resources': [
|
|
'2'
|
|
],
|
|
'parameters': [
|
|
'ControllerCount'
|
|
]
|
|
},
|
|
'2': {
|
|
'id': '2',
|
|
'name': 'CephStorageHostsDeployment',
|
|
'type': 'OS::Heat::StructuredDeployments'
|
|
}
|
|
},
|
|
'parameters': {
|
|
'ControllerCount': {
|
|
'default': 1,
|
|
'type': 'Number',
|
|
'name': 'ControllerCount'
|
|
}
|
|
},
|
|
},
|
|
'environment_parameters': None,
|
|
}
|
|
|
|
# Test
|
|
result = stack_parameters.get_flattened_parameters(swift, mock_heat)
|
|
self.assertEqual(result, expected_value)
|
|
|
|
def test_generate_hostmap(self):
|
|
|
|
# two instances in 'nova list'.
|
|
# vm1 with id=123 and vm2 with id=234
|
|
server1 = mock.MagicMock()
|
|
server1.id = 123
|
|
server1.name = 'vm1'
|
|
|
|
server2 = mock.MagicMock()
|
|
server2.id = 234
|
|
server2.name = 'vm2'
|
|
|
|
servers = mock.MagicMock()
|
|
servers = [server1, server2]
|
|
|
|
compute_client = mock.MagicMock()
|
|
compute_client.servers.list.side_effect = (servers, )
|
|
|
|
# we assume instance id=123 has been provisioned using bm node 'bm1'
|
|
# while instance id=234 is in error state, so no bm node has been used
|
|
|
|
def side_effect(args):
|
|
if args == 123:
|
|
return bm1
|
|
elif args == 234:
|
|
raise ironicexceptions.NotFound
|
|
|
|
baremetal_client = mock.MagicMock()
|
|
baremetal_client.node.get_by_instance_uuid = mock.MagicMock(
|
|
side_effect=side_effect)
|
|
|
|
# bm server with name='bm1' and uuid='9876'
|
|
bm1 = mock.MagicMock()
|
|
bm1.uuid = 9876
|
|
bm1.name = 'bm1'
|
|
|
|
# 'bm1' has a single port with mac='aa:bb:cc:dd:ee:ff'
|
|
port1 = mock.MagicMock()
|
|
port1.address = 'aa:bb:cc:dd:ee:ff'
|
|
|
|
def side_effect2(node, *args):
|
|
if node == 9876:
|
|
return [port1, ]
|
|
else:
|
|
raise ironicexceptions.NotFound
|
|
|
|
baremetal_client.port.list = mock.MagicMock(side_effect=side_effect2)
|
|
|
|
expected_hostmap = {
|
|
'aa:bb:cc:dd:ee:ff': {
|
|
'compute_name': 'vm1',
|
|
'baremetal_name': 'bm1'
|
|
}
|
|
}
|
|
|
|
result = nodes.generate_hostmap(baremetal_client, compute_client)
|
|
self.assertEqual(result, expected_hostmap)
|
|
|
|
@mock.patch('tripleo_common.utils.nodes.generate_hostmap')
|
|
def test_generate_fencing_parameters(self, mock_generate_hostmap):
|
|
test_hostmap = {
|
|
"00:11:22:33:44:55": {
|
|
"compute_name": "compute_name_0",
|
|
"baremetal_name": "baremetal_name_0"
|
|
},
|
|
"11:22:33:44:55:66": {
|
|
"compute_name": "compute_name_1",
|
|
"baremetal_name": "baremetal_name_1"
|
|
},
|
|
"aa:bb:cc:dd:ee:ff": {
|
|
"compute_name": "compute_name_4",
|
|
"baremetal_name": "baremetal_name_4"
|
|
},
|
|
"bb:cc:dd:ee:ff:gg": {
|
|
"compute_name": "compute_name_5",
|
|
"baremetal_name": "baremetal_name_5"
|
|
}
|
|
}
|
|
mock_generate_hostmap.return_value = test_hostmap
|
|
|
|
test_envjson = [{
|
|
"name": "control-0",
|
|
"pm_password": "control-0-password",
|
|
"pm_type": "ipmi",
|
|
"pm_user": "control-0-admin",
|
|
"pm_addr": "0.1.2.3",
|
|
"pm_port": "0123",
|
|
"mac": [
|
|
"00:11:22:33:44:55"
|
|
]
|
|
}, {
|
|
"name": "control-1",
|
|
"pm_password": "control-1-password",
|
|
# Still support deprecated drivers
|
|
"pm_type": "pxe_ipmitool",
|
|
"pm_user": "control-1-admin",
|
|
"pm_addr": "1.2.3.4",
|
|
"mac": [
|
|
"11:22:33:44:55:66"
|
|
]
|
|
}, {
|
|
# test node using redfish pm
|
|
"name": "compute-4",
|
|
"pm_password": "calvin",
|
|
"pm_type": "redfish",
|
|
"pm_user": "root",
|
|
"pm_addr": "172.16.0.1:8000",
|
|
"pm_port": "8000",
|
|
"redfish_verify_ca": "false",
|
|
"pm_system_id": "/redfish/v1/Systems/5678",
|
|
"mac": [
|
|
"aa:bb:cc:dd:ee:ff"
|
|
]
|
|
}, {
|
|
# This is an extra node on oVirt/RHV
|
|
"name": "control-3",
|
|
"pm_password": "ovirt-password",
|
|
"pm_type": "staging-ovirt",
|
|
"pm_user": "admin@internal",
|
|
"pm_addr": "3.4.5.6",
|
|
"pm_vm_name": "control-3",
|
|
"mac": [
|
|
"bb:cc:dd:ee:ff:gg"
|
|
]
|
|
}, {
|
|
# This is an extra node that is not in the hostmap, to ensure we
|
|
# cope with unprovisioned nodes
|
|
"name": "control-2",
|
|
"pm_password": "control-2-password",
|
|
"pm_type": "ipmi",
|
|
"pm_user": "control-2-admin",
|
|
"pm_addr": "2.3.4.5",
|
|
"mac": [
|
|
"22:33:44:55:66:77"
|
|
]
|
|
}
|
|
]
|
|
|
|
ironic = mock.MagicMock()
|
|
compute = mock.MagicMock()
|
|
|
|
result = stack_parameters.generate_fencing_parameters(
|
|
ironic, compute, test_envjson,
|
|
28, 5, 0, True)['parameter_defaults']
|
|
|
|
self.assertTrue(result["EnableFencing"])
|
|
self.assertEqual(len(result["FencingConfig"]["devices"]), 4)
|
|
self.assertEqual(result["FencingConfig"]["devices"][0], {
|
|
"agent": "fence_ipmilan",
|
|
"host_mac": "00:11:22:33:44:55",
|
|
"params": {
|
|
"delay": 28,
|
|
"ipaddr": "0.1.2.3",
|
|
"ipport": "0123",
|
|
"lanplus": True,
|
|
"privlvl": 5,
|
|
"login": "control-0-admin",
|
|
"passwd": "control-0-password",
|
|
"pcmk_host_list": "compute_name_0"
|
|
}
|
|
})
|
|
self.assertEqual(result["FencingConfig"]["devices"][1], {
|
|
"agent": "fence_ipmilan",
|
|
"host_mac": "11:22:33:44:55:66",
|
|
"params": {
|
|
"delay": 28,
|
|
"ipaddr": "1.2.3.4",
|
|
"lanplus": True,
|
|
"privlvl": 5,
|
|
"login": "control-1-admin",
|
|
"passwd": "control-1-password",
|
|
"pcmk_host_list": "compute_name_1"
|
|
}
|
|
})
|
|
self.assertEqual(result["FencingConfig"]["devices"][2], {
|
|
"agent": "fence_redfish",
|
|
"host_mac": "aa:bb:cc:dd:ee:ff",
|
|
"params": {
|
|
"delay": 28,
|
|
"ipaddr": "172.16.0.1:8000",
|
|
"ipport": "8000",
|
|
"privlvl": 5,
|
|
"login": "root",
|
|
"passwd": "calvin",
|
|
"systems_uri": "/redfish/v1/Systems/5678",
|
|
"ssl_insecure": "true",
|
|
"pcmk_host_list": "compute_name_4"
|
|
}
|
|
})
|
|
self.assertEqual(result["FencingConfig"]["devices"][3], {
|
|
"agent": "fence_rhevm",
|
|
"host_mac": "bb:cc:dd:ee:ff:gg",
|
|
"params": {
|
|
"delay": 28,
|
|
"ipaddr": "3.4.5.6",
|
|
"login": "admin@internal",
|
|
"passwd": "ovirt-password",
|
|
"port": "control-3",
|
|
"ssl": 1,
|
|
"ssl_insecure": 1,
|
|
"pcmk_host_list": "compute_name_5"
|
|
}
|
|
})
|
|
|
|
@mock.patch('tripleo_common.utils.template.process_templates')
|
|
def test_run_valid_network_config(self, mock_process_templates):
|
|
swift = mock.MagicMock(url="http://test.com")
|
|
|
|
mock_env = {
|
|
'template': {},
|
|
'files': {},
|
|
'environment': [{'path': 'environments/test.yaml'}]
|
|
}
|
|
|
|
mock_process_templates.return_value = mock_env
|
|
mock_heat = mock.MagicMock()
|
|
|
|
mock_heat.stacks.preview.return_value = mock.Mock(resources=[{
|
|
"resource_identity": {"stack_name": "overcloud-TEMP-Compute-0"},
|
|
"resource_name": "OsNetConfigImpl",
|
|
"properties": {"config": "echo \'{\"network_config\": {}}\'"
|
|
" > /etc/os-net-config/config.json"}
|
|
}])
|
|
|
|
mock_heat.stacks.get.return_value = mock.Mock(
|
|
stack_name="overcloud-TEMP")
|
|
|
|
expected = {"network_config": {}}
|
|
# Test
|
|
result = stack_parameters.get_network_configs(
|
|
swift, mock_heat, container='overcloud', role_name='Compute')
|
|
self.assertEqual(expected, result)
|
|
mock_heat.stacks.preview.assert_called_once_with(
|
|
environment=[{'path': 'environments/test.yaml'}],
|
|
files={},
|
|
template={},
|
|
stack_name='overcloud-TEMP',
|
|
)
|
|
|
|
@mock.patch('tripleo_common.utils.template.process_templates')
|
|
def test_run_invalid_network_config(self, mock_process_templates):
|
|
swift = mock.MagicMock(url="http://test.com")
|
|
|
|
mock_env = {
|
|
'template': {},
|
|
'files': {},
|
|
'environment': [{'path': 'environments/test.yaml'}]
|
|
}
|
|
|
|
mock_process_templates.return_value = mock_env
|
|
mock_heat = mock.MagicMock()
|
|
|
|
mock_heat.stacks.preview.return_value = mock.Mock(resources=[{
|
|
"resource_identity": {"stack_name": "overcloud-TEMP-Compute-0"},
|
|
"resource_name": "OsNetConfigImpl",
|
|
"properties": {"config": ""}
|
|
}])
|
|
|
|
mock_heat.stacks.get.return_value = mock.Mock(
|
|
stack_name="overcloud-TEMP")
|
|
|
|
# Test
|
|
self.assertRaises(RuntimeError,
|
|
stack_parameters.get_network_configs, swift,
|
|
mock_heat, container='overcloud',
|
|
role_name='Compute')
|
|
mock_heat.stacks.preview.assert_called_once_with(
|
|
environment=[{'path': 'environments/test.yaml'}],
|
|
files={},
|
|
template={},
|
|
stack_name='overcloud-TEMP',
|
|
)
|
|
|
|
@mock.patch('tripleo_common.utils.template.process_templates')
|
|
def test_run_valid_network_config_with_no_if_routes_inputs(
|
|
self, mock_process_templates):
|
|
swift = mock.MagicMock(url="http://test.com")
|
|
|
|
mock_env = {
|
|
'template': {
|
|
'resources': {
|
|
'ComputeGroupVars': {
|
|
'properties': {
|
|
'value': {
|
|
'role_networks': ['InternalApi',
|
|
'Storage']}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
'files': {},
|
|
'environment': {'parameter_defaults': {}}
|
|
}
|
|
|
|
mock_process_templates.return_value = mock_env
|
|
mock_heat = mock.MagicMock()
|
|
|
|
mock_heat.stacks.preview.return_value = mock.Mock(resources=[{
|
|
"resource_identity": {"stack_name": "overcloud-TEMP-Compute-0"},
|
|
"resource_name": "OsNetConfigImpl",
|
|
"properties": {"config": "echo \'{\"network_config\": {}}\'"
|
|
" > /etc/os-net-config/config.json"}
|
|
}])
|
|
|
|
mock_heat.stacks.get.return_value = mock.Mock(
|
|
stack_name="overcloud-TEMP")
|
|
|
|
expected = {"network_config": {}}
|
|
# Test
|
|
result = stack_parameters.get_network_configs(
|
|
swift, mock_heat, container='overcloud', role_name='Compute')
|
|
self.assertEqual(expected, result)
|
|
mock_heat.stacks.preview.assert_called_once_with(
|
|
environment={
|
|
'parameter_defaults': {
|
|
'InternalApiInterfaceRoutes': [[]],
|
|
'StorageInterfaceRoutes': [[]]
|
|
}
|
|
},
|
|
files={},
|
|
template={'resources': {'ComputeGroupVars': {'properties': {
|
|
'value': {'role_networks': ['InternalApi', 'Storage']}
|
|
}}}},
|
|
stack_name='overcloud-TEMP',
|
|
)
|
|
|
|
@mock.patch('tripleo_common.utils.template.process_templates')
|
|
def test_run_valid_network_config_with_if_routes_inputs(
|
|
self, mock_process_templates):
|
|
swift = mock.MagicMock(url="http://test.com")
|
|
|
|
mock_env = {
|
|
'template': {
|
|
'resources': {
|
|
'ComputeGroupVars': {
|
|
'properties': {
|
|
'value': {
|
|
'role_networks': ['InternalApi',
|
|
'Storage']}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
'files': {},
|
|
'environment': {
|
|
'parameter_defaults': {
|
|
'InternalApiInterfaceRoutes': ['test1'],
|
|
'StorageInterfaceRoutes': ['test2']
|
|
}}
|
|
}
|
|
|
|
mock_process_templates.return_value = mock_env
|
|
mock_heat = mock.MagicMock()
|
|
|
|
mock_heat.stacks.preview.return_value = mock.Mock(resources=[{
|
|
"resource_identity": {"stack_name": "overcloud-TEMP-Compute-0"},
|
|
"resource_name": "OsNetConfigImpl",
|
|
"properties": {"config": "echo \'{\"network_config\": {}}\'"
|
|
" > /etc/os-net-config/config.json"}
|
|
}])
|
|
|
|
mock_heat.stacks.get.return_value = mock.Mock(
|
|
stack_name="overcloud-TEMP")
|
|
|
|
expected = {"network_config": {}}
|
|
# Test
|
|
result = stack_parameters.get_network_configs(
|
|
swift, mock_heat, container='overcloud', role_name='Compute')
|
|
self.assertEqual(expected, result)
|
|
mock_heat.stacks.preview.assert_called_once_with(
|
|
environment={
|
|
'parameter_defaults': {
|
|
'InternalApiInterfaceRoutes': ['test1'],
|
|
'StorageInterfaceRoutes': ['test2']
|
|
}
|
|
},
|
|
files={},
|
|
template={'resources': {'ComputeGroupVars': {'properties': {
|
|
'value': {'role_networks': ['InternalApi', 'Storage']}
|
|
}}}},
|
|
stack_name='overcloud-TEMP',
|
|
)
|