Merge "Identify not allowed parameters in upgrades." into stable/ussuri

This commit is contained in:
Zuul 2020-07-03 04:01:45 +00:00 committed by Gerrit Code Review
commit cf666626a0
4 changed files with 103 additions and 0 deletions

View File

@ -79,6 +79,14 @@ UPDATE_PREPARE_ENV = "environments/lifecycle/update-prepare.yaml"
UPDATE_CONVERGE_ENV = "environments/lifecycle/update-converge.yaml"
UPGRADE_PREPARE_ENV = "environments/lifecycle/upgrade-prepare.yaml"
UPGRADE_CONVERGE_ENV = "environments/lifecycle/upgrade-converge.yaml"
UPGRADE_CONVERGE_FORBIDDEN_PARAMS = ["ceph3_namespace",
"ceph3_tag",
"ceph3_image",
"name_prefix_stein",
"name_suffix_stein",
"namespace_stein",
"tag_stein",
]
FFWD_UPGRADE_PREPARE_ENV = "environments/lifecycle/ffwd-upgrade-prepare.yaml"
FFWD_UPGRADE_CONVERGE_ENV = "environments/lifecycle/ffwd-upgrade-converge.yaml"

View File

@ -123,3 +123,7 @@ class UndercloudUpgradeNotConfirmed(Base):
class CellExportError(Base):
"""Cell export failed"""
class BannedParameters(Base):
"""Some of the environment parameters provided should be removed"""

View File

@ -24,6 +24,7 @@ from tripleoclient import exceptions
from tripleoclient import utils as oooutils
from tripleoclient.v1.overcloud_deploy import DeployOvercloud
from tripleoclient.workflows import deployment
from tripleoclient.workflows import parameters
CONF = cfg.CONF
logging.register_options(CONF)
@ -42,6 +43,8 @@ class UpgradePrepare(DeployOvercloud):
template = constants.UPGRADE_PREPARE_ENV
forbidden_params = []
log = logging.getLogger(__name__ + ".UpgradePrepare")
def get_parser(self, prog_name):
@ -74,6 +77,11 @@ class UpgradePrepare(DeployOvercloud):
parsed_args.environment_files = oooutils.prepend_environment(
parsed_args.environment_files, templates_dir,
self.template)
# Parse all environment files looking for undesired
# parameters
parameters.check_forbidden_params(self.log,
parsed_args.environment_files,
self.forbidden_params)
super(UpgradePrepare, self).take_action(parsed_args)
# enable ssh admin for Ansible-via-Mistral as that's done only
@ -242,4 +250,6 @@ class UpgradeConvergeOvercloud(UpgradePrepare):
template = constants.UPGRADE_CONVERGE_ENV
forbidden_params = constants.UPGRADE_CONVERGE_FORBIDDEN_PARAMS
log = logging.getLogger(__name__ + ".UpgradeConvergeOvercloud")

View File

@ -252,3 +252,84 @@ def generate_fencing_parameters(clients, nodes_json, delay, ipmi_level,
ipmi_level=ipmi_level,
ipmi_cipher=ipmi_cipher,
ipmi_lanplus=ipmi_lanplus)
def check_forbidden_params(log, env_files, forbidden):
"""Looks for undesired parameters in the environment files.
Each of the environment files pass in env_files will be parsed
and if the parameters_default key is found, then all the keys
from the nested dictionary found under will be converted into
a list, for example:
parameters_default:
key1: value1
key2: value2
key3:
- value3
- key31:
key311: value311
key312: value312
key32: value32
Will be converted by get_all_keys into:
[key1, key2, key3, key31, key311, key312, key32]
This list provides us with all the parameters used in the environment
file, without the values, in the format of a list. So we can use sets
to find occurrences of the forbbiden paramenters.
The variable matched_params will get all the ocurrences of forbidden
parameters stored, so we can parse all the environment files and show
all the parameters which should get removed from the environment files
at once (saving the user to run the command, modify a template, run it
again, modify another, etc...). If matched_params list is not empty,
an exception will be raised, stopping the execution of the command and
displaying the commands which need to be removed.
:param log: logging object passed from the calling method
:type log: Logging object
:param env_files: list of the environment files passed in the command
:type env_files: list of strings
:param forbidden: list of the undesired parameters
:type forbidden: list of strings
:returns exception if some of the forbidden parameters are found in
the environment files.
"""
# Iterates over a nested dict and returns all the
# keys from the dict in a list
# example:
# * input: {'a': '1', 'b': ['c': '2', 'd': {'e': '3'}]}
# * output: ['a', 'b', 'c', 'd', 'e']
def get_all_keys(obj, keys_list):
if isinstance(obj, dict):
keys_list += obj.keys()
for value in obj.values():
get_all_keys(value, keys_list)
elif isinstance(obj, list):
for value in obj:
get_all_keys(value, keys_list)
matched_params = []
for file in env_files:
if os.path.exists(file):
with open(file, 'r') as env_file:
contents = yaml.safe_load(env_file)
pd = contents.get('parameter_defaults', {})
if pd:
# Intersection of values and forbidden params
list_of_keys = []
get_all_keys(pd, list_of_keys)
found_in_pd = list(set(list_of_keys) & set(forbidden))
# Combine them without duplicates
matched_params = list(set(matched_params + found_in_pd))
if matched_params:
raise exceptions.BannedParameters("The following parameters should be "
"removed from the environment files:"
"\n{}\n"
.format('\n'.join(matched_params)))