Fixes ordering of environment files in a deployment plan
Sometimes making changes in basic deployment breaks the order of
passed env files and leads to a failed deployment. This patch
orders the environment files according to the rules defined in
the capabilities-map.yaml file.
Change-Id: Idbb6f0f3adebebd429bcb3447e559838180f4b1c
(cherry picked from commit bae4296502
)
This commit is contained in:
parent
451aace65e
commit
e95d51f989
|
@ -193,6 +193,23 @@ class UpdateCapabilitiesAction(base.TripleOAction):
|
|||
|
||||
self.cache_delete(context, self.container, "tripleo.parameters.get")
|
||||
|
||||
# get the capabilities-map content to perform the environment ordering
|
||||
try:
|
||||
swift = self.get_object_client(context)
|
||||
map_file = swift.get_object(
|
||||
self.container, 'capabilities-map.yaml')
|
||||
capabilities = yaml.safe_load(map_file[1])
|
||||
except swiftexceptions.ClientException as err:
|
||||
err_msg = ("Error retrieving capabilities-map.yaml for "
|
||||
"plan %s: %s" % (self.container, err))
|
||||
LOG.exception(err_msg)
|
||||
return actions.Result(error=err_msg)
|
||||
|
||||
ordered_env = plan_utils.apply_environments_order(
|
||||
capabilities, env.get('environments', []))
|
||||
|
||||
env['environments'] = ordered_env
|
||||
|
||||
try:
|
||||
plan_utils.put_env(swift, env)
|
||||
except swiftexceptions.ClientException as err:
|
||||
|
|
|
@ -246,7 +246,9 @@ class UpdateCapabilitiesActionTest(base.TestCase):
|
|||
- path: /path/to/overcloud-default-env.yaml
|
||||
- path: /path/to/ceph-storage-env.yaml
|
||||
"""
|
||||
swift.get_object.return_value = ({}, mocked_env)
|
||||
swift.get_object.side_effect = (
|
||||
({}, mocked_env),
|
||||
({}, MAPPING_YAML_CONTENTS))
|
||||
get_object_client_mock.return_value = swift
|
||||
|
||||
environments = {
|
||||
|
@ -287,7 +289,9 @@ class UpdateCapabilitiesActionTest(base.TestCase):
|
|||
- path: /path/to/overcloud-default-env.yaml
|
||||
- path: /path/to/ceph-storage-env.yaml
|
||||
"""
|
||||
swift.get_object.return_value = ({}, mocked_env)
|
||||
swift.get_object.side_effect = (
|
||||
({}, mocked_env),
|
||||
({}, MAPPING_YAML_CONTENTS))
|
||||
get_object_client_mock.return_value = swift
|
||||
|
||||
environments = {
|
||||
|
|
|
@ -37,6 +37,41 @@ passwords:
|
|||
ZaqarPassword: zzzz
|
||||
"""
|
||||
|
||||
USER_ENV_CONTENTS = """
|
||||
resource_registry:
|
||||
OS::TripleO::Foo: bar.yaml
|
||||
"""
|
||||
|
||||
UNORDERED_PLAN_ENV_LIST = [
|
||||
{'path': 'overcloud-resource-registry-puppet.yaml'},
|
||||
{'path': 'environments/docker-ha.yaml'},
|
||||
{'path': 'environments/containers-default-parameters.yaml'},
|
||||
{'path': 'environments/docker.yaml'}
|
||||
]
|
||||
|
||||
CAPABILITIES_DICT = {
|
||||
'topics': [{
|
||||
'environment_groups': [{
|
||||
'environments': [{
|
||||
'file': 'overcloud-resource-registry-puppet.yaml'}
|
||||
]}, {
|
||||
'environments': [{
|
||||
'file': 'environments/docker.yaml',
|
||||
'requires': ['overcloud-resource-registry-puppet.yaml']
|
||||
}, {
|
||||
'file': 'environments/containers-default-parameters.yaml',
|
||||
'requires': ['overcloud-resource-registry-puppet.yaml',
|
||||
'environments/docker.yaml']
|
||||
}]}, {
|
||||
'environments': [{
|
||||
'file': 'environments/docker-ha.yaml',
|
||||
'requires': ['overcloud-resource-registry-puppet.yaml',
|
||||
'environments/docker.yaml']
|
||||
}]}
|
||||
]
|
||||
}]
|
||||
}
|
||||
|
||||
|
||||
class PlanTest(base.TestCase):
|
||||
def setUp(self):
|
||||
|
@ -90,3 +125,15 @@ class PlanTest(base.TestCase):
|
|||
|
||||
self.swift.get_object.assert_called()
|
||||
self.swift.put_object.assert_called()
|
||||
|
||||
def test_apply_env_order(self):
|
||||
ordered_plan_env_list = [
|
||||
{'path': 'overcloud-resource-registry-puppet.yaml'},
|
||||
{'path': 'environments/docker.yaml'},
|
||||
{'path': 'environments/docker-ha.yaml'},
|
||||
{'path': 'environments/containers-default-parameters.yaml'}
|
||||
]
|
||||
|
||||
ordered_env = plan_utils.apply_environments_order(
|
||||
CAPABILITIES_DICT, UNORDERED_PLAN_ENV_LIST)
|
||||
self.assertEqual(ordered_env, ordered_plan_env_list)
|
||||
|
|
|
@ -56,3 +56,42 @@ def put_env(swift, env):
|
|||
constants.PLAN_ENVIRONMENT,
|
||||
yaml.safe_dump(env, default_flow_style=False)
|
||||
)
|
||||
|
||||
|
||||
def apply_environments_order(capabilities, environments):
|
||||
"""traverses the capabilities and orders the environment files
|
||||
|
||||
by dependency rules defined in capabilities-map, so that parent
|
||||
environments are first and children environments override these
|
||||
parents
|
||||
|
||||
:param capabilities: dict representing capabilities-map.yaml file
|
||||
:param environments: list representing the environments section of the
|
||||
plan-environments.yaml file
|
||||
:return: list containing ordered environments
|
||||
|
||||
"""
|
||||
# get ordering rules from capabilities-map file
|
||||
order_rules = {}
|
||||
for topic in capabilities.get('topics', []):
|
||||
for group in topic.get('environment_groups', []):
|
||||
for environment in group.get('environments', []):
|
||||
order_rules[environment['file']] = []
|
||||
if 'requires' in environment:
|
||||
order_rules[environment['file']] \
|
||||
= environment.get('requires', [])
|
||||
|
||||
# apply ordering rules
|
||||
for e in environments:
|
||||
path = e.get('path', '')
|
||||
if path not in order_rules:
|
||||
continue
|
||||
path_pos = environments.index(e)
|
||||
for requirement in order_rules[path]:
|
||||
if {'path': requirement} in environments:
|
||||
requirement_pos = environments.index({'path': requirement})
|
||||
if requirement_pos > path_pos:
|
||||
item = environments.pop(requirement_pos)
|
||||
environments.insert(path_pos, item)
|
||||
|
||||
return environments
|
||||
|
|
Loading…
Reference in New Issue