Merge "Match hostname when doing node delete" into stable/rocky
This commit is contained in:
commit
8c42d4fa23
|
@ -120,20 +120,37 @@ class ScaleDownAction(templates.ProcessTemplatesAction):
|
||||||
|
|
||||||
return stack_params
|
return stack_params
|
||||||
|
|
||||||
|
def _match_hostname(self, heatclient, instance_list, res, stack_name):
|
||||||
|
type_patterns = ['DeployedServer', 'Server']
|
||||||
|
if any(res.resource_type.endswith(x) for x in type_patterns):
|
||||||
|
res_details = heatclient.resources.get(
|
||||||
|
stack_name, res.resource_name)
|
||||||
|
if 'name' in res_details.attributes:
|
||||||
|
try:
|
||||||
|
instance_list.remove(res_details.attributes['name'])
|
||||||
|
return True
|
||||||
|
except ValueError:
|
||||||
|
return False
|
||||||
|
return False
|
||||||
|
|
||||||
def run(self, context):
|
def run(self, context):
|
||||||
heatclient = self.get_orchestration_client(context)
|
heatclient = self.get_orchestration_client(context)
|
||||||
resources = heatclient.resources.list(self.container, nested_depth=5)
|
resources = heatclient.resources.list(self.container, nested_depth=5)
|
||||||
resources_by_role = collections.defaultdict(list)
|
resources_by_role = collections.defaultdict(list)
|
||||||
instance_list = list(self.nodes)
|
instance_list = list(self.nodes)
|
||||||
for res in resources:
|
|
||||||
try:
|
|
||||||
instance_list.remove(res.physical_resource_id)
|
|
||||||
except ValueError:
|
|
||||||
continue
|
|
||||||
|
|
||||||
|
for res in resources:
|
||||||
stack_name, stack_id = next(
|
stack_name, stack_id = next(
|
||||||
x['href'] for x in res.links if
|
x['href'] for x in res.links if
|
||||||
x['rel'] == 'stack').rsplit('/', 2)[1:]
|
x['rel'] == 'stack').rsplit('/', 2)[1:]
|
||||||
|
|
||||||
|
try:
|
||||||
|
instance_list.remove(res.physical_resource_id)
|
||||||
|
except ValueError:
|
||||||
|
if not self._match_hostname(
|
||||||
|
heatclient, instance_list, res, stack_name):
|
||||||
|
continue
|
||||||
|
|
||||||
# get resource to remove from resource group (it's parent resource
|
# get resource to remove from resource group (it's parent resource
|
||||||
# of nova server)
|
# of nova server)
|
||||||
role_resource = next(x for x in resources if
|
role_resource = next(x for x in resources if
|
||||||
|
|
|
@ -73,7 +73,7 @@ class ScaleDownActionTest(base.TestCase):
|
||||||
'a959ac7d6a4a475daf2428df315c41ef/'
|
'a959ac7d6a4a475daf2428df315c41ef/'
|
||||||
'stacks/overcloud/124'}],
|
'stacks/overcloud/124'}],
|
||||||
logical_resource_id='node0',
|
logical_resource_id='node0',
|
||||||
physical_resource_id='123',
|
physical_resource_id='124',
|
||||||
resource_type='OS::TripleO::Compute',
|
resource_type='OS::TripleO::Compute',
|
||||||
parent_resource='Compute',
|
parent_resource='Compute',
|
||||||
resource_name='node0',
|
resource_name='node0',
|
||||||
|
@ -130,7 +130,7 @@ class ScaleDownActionTest(base.TestCase):
|
||||||
|
|
||||||
# Test
|
# Test
|
||||||
action = scale.ScaleDownAction(
|
action = scale.ScaleDownAction(
|
||||||
constants.STACK_TIMEOUT_DEFAULT, ['resource_id'], 'stack')
|
constants.STACK_TIMEOUT_DEFAULT, ['124'], 'stack')
|
||||||
result = action.run(mock_ctx)
|
result = action.run(mock_ctx)
|
||||||
|
|
||||||
heatclient.stacks.validate.assert_called_once_with(
|
heatclient.stacks.validate.assert_called_once_with(
|
||||||
|
@ -203,3 +203,119 @@ class ScaleDownActionTest(base.TestCase):
|
||||||
result = action.run(mock_ctx)
|
result = action.run(mock_ctx)
|
||||||
|
|
||||||
self.assertEqual(actions.Result(error='Update error'), result)
|
self.assertEqual(actions.Result(error='Update error'), result)
|
||||||
|
|
||||||
|
@mock.patch('tripleo_common.actions.base.TripleOAction.'
|
||||||
|
'cache_delete')
|
||||||
|
@mock.patch('tripleo_common.actions.base.TripleOAction.'
|
||||||
|
'get_orchestration_client')
|
||||||
|
@mock.patch('heatclient.common.template_utils.'
|
||||||
|
'process_multiple_environments_and_files')
|
||||||
|
@mock.patch('heatclient.common.template_utils.get_template_contents')
|
||||||
|
@mock.patch('tripleo_common.actions.base.TripleOAction.get_object_client')
|
||||||
|
def test_run_with_hostmatch(self, mock_get_object_client,
|
||||||
|
mock_get_template_contents, mock_env_files,
|
||||||
|
mock_get_heat_client, mock_cache):
|
||||||
|
|
||||||
|
mock_env_files.return_value = ({}, {})
|
||||||
|
heatclient = mock.MagicMock()
|
||||||
|
heatclient.resources.list.return_value = [
|
||||||
|
mock.MagicMock(
|
||||||
|
links=[{'rel': 'stack',
|
||||||
|
'href': 'http://192.0.2.1:8004/v1/'
|
||||||
|
'a959ac7d6a4a475daf2428df315c41ef/'
|
||||||
|
'stacks/overcloud/123'}],
|
||||||
|
logical_resource_id='logical_id',
|
||||||
|
physical_resource_id='resource_id',
|
||||||
|
resource_type='OS::Heat::ResourceGroup',
|
||||||
|
resource_name='Compute'
|
||||||
|
),
|
||||||
|
mock.MagicMock(
|
||||||
|
links=[{'rel': 'stack',
|
||||||
|
'href': 'http://192.0.2.1:8004/v1/'
|
||||||
|
'a959ac7d6a4a475daf2428df315c41ef/'
|
||||||
|
'stacks/overcloud/124'}],
|
||||||
|
logical_resource_id='node0',
|
||||||
|
physical_resource_id='124',
|
||||||
|
resource_type='OS::TripleO::ComputeServer',
|
||||||
|
parent_resource='Compute',
|
||||||
|
resource_name='node0',
|
||||||
|
)
|
||||||
|
]
|
||||||
|
heatclient.resources.get.return_value = mock.MagicMock(
|
||||||
|
attributes={'name': 'node0'})
|
||||||
|
heatclient.stacks.get.return_value = mock_stack()
|
||||||
|
heatclient.stacks.validate.return_value = {}
|
||||||
|
mock_get_heat_client.return_value = heatclient
|
||||||
|
|
||||||
|
mock_ctx = mock.MagicMock()
|
||||||
|
swift = mock.MagicMock(url="http://test.com")
|
||||||
|
mock_env = yaml.safe_dump({
|
||||||
|
'name': 'overcloud',
|
||||||
|
'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_get_object_client.return_value = swift
|
||||||
|
|
||||||
|
env = {
|
||||||
|
'resource_registry': {
|
||||||
|
'resources': {'*': {'*': {'UpdateDeployment': {'hooks': []}}}}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mock_get_template_contents.return_value = ({}, {
|
||||||
|
'heat_template_version': '2016-04-30'
|
||||||
|
})
|
||||||
|
|
||||||
|
# Test
|
||||||
|
action = scale.ScaleDownAction(
|
||||||
|
constants.STACK_TIMEOUT_DEFAULT, ['node0'], 'stack')
|
||||||
|
result = action.run(mock_ctx)
|
||||||
|
|
||||||
|
heatclient.stacks.validate.assert_called_once_with(
|
||||||
|
environment=env,
|
||||||
|
files={},
|
||||||
|
show_nested=True,
|
||||||
|
template={'heat_template_version': '2016-04-30'}
|
||||||
|
)
|
||||||
|
|
||||||
|
clear_list = list(['ComputeCount', 'ComputeRemovalPolicies',
|
||||||
|
'ComputeRemovalPoliciesMode'])
|
||||||
|
_, kwargs = heatclient.stacks.update.call_args
|
||||||
|
self.assertEqual(set(kwargs['clear_parameters']), set(clear_list))
|
||||||
|
self.assertEqual(kwargs['environment'], env)
|
||||||
|
self.assertEqual(kwargs['existing'], True)
|
||||||
|
self.assertEqual(kwargs['files'], {})
|
||||||
|
|
||||||
|
mock_cache.assert_called_with(
|
||||||
|
mock_ctx,
|
||||||
|
"stack",
|
||||||
|
"tripleo.parameters.get"
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(None, result)
|
||||||
|
|
Loading…
Reference in New Issue