Identify not allowed parameters in upgrades.
This change allows us identifying a set of parameters which should not been passed in the upgrade prepare or upgrade converge steps. As it is now, it is mostly intended to block the converge step if the FFU parameters (Stein registry parameters) were left in the environment files before running the converge step, however it will allow blocking the upgrade prepare in the case that some deprecated or not recommended parameter is provided in the templates. The way how it works is by converting every single yaml passed in the environment files into a list of keys (only for the parameters_default so far), then it will try to intersect the list of forbidden parameters with the list of keys. If there is a match an exception will be raised showing those parameters: ERROR openstack [-] The following parameters should be removed from the environment files: ceph3_namespace name_suffix_stein tag_stein name_prefix_stein ceph3_image namespace_stein ceph3_tag Change-Id: I24715f5e55d4cd6cf9879345980d3a3c5ab8830c (cherry picked from commitfbc1eba88a
) (cherry picked from commit3a86f9f7f5
)
This commit is contained in:
parent
f0c2113cbb
commit
57ed1b8872
|
@ -78,6 +78,14 @@ UPDATE_PREPARE_ENV = "environments/lifecycle/update-prepare.yaml"
|
||||||
UPDATE_CONVERGE_ENV = "environments/lifecycle/update-converge.yaml"
|
UPDATE_CONVERGE_ENV = "environments/lifecycle/update-converge.yaml"
|
||||||
UPGRADE_PREPARE_ENV = "environments/lifecycle/upgrade-prepare.yaml"
|
UPGRADE_PREPARE_ENV = "environments/lifecycle/upgrade-prepare.yaml"
|
||||||
UPGRADE_CONVERGE_ENV = "environments/lifecycle/upgrade-converge.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_PREPARE_ENV = "environments/lifecycle/ffwd-upgrade-prepare.yaml"
|
||||||
FFWD_UPGRADE_CONVERGE_ENV = "environments/lifecycle/ffwd-upgrade-converge.yaml"
|
FFWD_UPGRADE_CONVERGE_ENV = "environments/lifecycle/ffwd-upgrade-converge.yaml"
|
||||||
FFWD_UPGRADE_PREPARE_SCRIPT = ("#!/bin/bash \n"
|
FFWD_UPGRADE_PREPARE_SCRIPT = ("#!/bin/bash \n"
|
||||||
|
|
|
@ -135,3 +135,7 @@ class UndercloudUpgradeNotConfirmed(Base):
|
||||||
|
|
||||||
class CellExportError(Base):
|
class CellExportError(Base):
|
||||||
"""Cell export failed"""
|
"""Cell export failed"""
|
||||||
|
|
||||||
|
|
||||||
|
class BannedParameters(Base):
|
||||||
|
"""Some of the environment parameters provided should be removed"""
|
||||||
|
|
|
@ -25,6 +25,7 @@ from tripleoclient import utils as oooutils
|
||||||
from tripleoclient.v1.overcloud_deploy import DeployOvercloud
|
from tripleoclient.v1.overcloud_deploy import DeployOvercloud
|
||||||
from tripleoclient.workflows import deployment
|
from tripleoclient.workflows import deployment
|
||||||
from tripleoclient.workflows import package_update
|
from tripleoclient.workflows import package_update
|
||||||
|
from tripleoclient.workflows import parameters
|
||||||
|
|
||||||
CONF = cfg.CONF
|
CONF = cfg.CONF
|
||||||
logging.register_options(CONF)
|
logging.register_options(CONF)
|
||||||
|
@ -43,6 +44,8 @@ class UpgradePrepare(DeployOvercloud):
|
||||||
|
|
||||||
template = constants.UPGRADE_PREPARE_ENV
|
template = constants.UPGRADE_PREPARE_ENV
|
||||||
|
|
||||||
|
forbidden_params = []
|
||||||
|
|
||||||
log = logging.getLogger(__name__ + ".UpgradePrepare")
|
log = logging.getLogger(__name__ + ".UpgradePrepare")
|
||||||
|
|
||||||
def get_parser(self, prog_name):
|
def get_parser(self, prog_name):
|
||||||
|
@ -75,6 +78,11 @@ class UpgradePrepare(DeployOvercloud):
|
||||||
parsed_args.environment_files = oooutils.prepend_environment(
|
parsed_args.environment_files = oooutils.prepend_environment(
|
||||||
parsed_args.environment_files, templates_dir,
|
parsed_args.environment_files, templates_dir,
|
||||||
self.template)
|
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)
|
super(UpgradePrepare, self).take_action(parsed_args)
|
||||||
|
|
||||||
# Download stack_name-config as this is skiped in
|
# Download stack_name-config as this is skiped in
|
||||||
|
@ -256,4 +264,6 @@ class UpgradeConvergeOvercloud(UpgradePrepare):
|
||||||
|
|
||||||
template = constants.UPGRADE_CONVERGE_ENV
|
template = constants.UPGRADE_CONVERGE_ENV
|
||||||
|
|
||||||
|
forbidden_params = constants.UPGRADE_CONVERGE_FORBIDDEN_PARAMS
|
||||||
|
|
||||||
log = logging.getLogger(__name__ + ".UpgradeConvergeOvercloud")
|
log = logging.getLogger(__name__ + ".UpgradeConvergeOvercloud")
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
import logging
|
import logging
|
||||||
|
import os
|
||||||
import re
|
import re
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
|
@ -156,3 +157,84 @@ def generate_fencing_parameters(clients, **workflow_input):
|
||||||
if ('fencing_parameters' in payload and
|
if ('fencing_parameters' in payload and
|
||||||
(payload.get('status', 'FAILED') == "SUCCESS")):
|
(payload.get('status', 'FAILED') == "SUCCESS")):
|
||||||
return payload['fencing_parameters']
|
return payload['fencing_parameters']
|
||||||
|
|
||||||
|
|
||||||
|
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)))
|
||||||
|
|
Loading…
Reference in New Issue