From d1084193f6d60559f28b8b71fc0f0f6c032b09c7 Mon Sep 17 00:00:00 2001 From: Gael Chamoulaud Date: Thu, 11 Jul 2019 18:39:26 +0200 Subject: [PATCH] Add --parameters and --create-vars-file arguments to the list subcommand The 'openstack tripleo validator list' subcommand can now get only the available parameters for the validations using the new --parameters argument. ``` $ openstack tripleo validator list \ --parameters \ [--validation-name [,,...] | --group [,,...]] ``` Here is an output example: ``` Waiting for messages on queue 'tripleo' with no timeout. { "undercloud-cpu": { "parameters": { "min_undercloud_cpu_count": 8 } }, "undercloud-ram": { "parameters": { "min_undercloud_ram_gb": 24 } } } ``` The --create-vars-file allow the operator to generate either a JSON or a YAML file containing only the parameters of one or multiple validations. This file will be available to pass as extra vars to the validations execution. ``` $ openstack tripleo validator list \ --parameters \ --create-vars-file [json|yaml] /home/stack/myvars \ [--validation-name [,,...] | --group [,,...]] ``` Change-Id: I6e2255c0d490ee8105f0757d02f5d8fba1d4fa20 Signed-off-by: Gael Chamoulaud --- ..._the_list_subcommand-2e0944e5440c4216.yaml | 6 ++ tripleoclient/tests/test_utils.py | 45 +++++++++ .../test_tripleo_validator.py} | 0 tripleoclient/utils.py | 53 +++++++++-- tripleoclient/v1/tripleo_validator.py | 93 +++++++++++++++++-- 5 files changed, 185 insertions(+), 12 deletions(-) create mode 100644 releasenotes/notes/Add_parameters_and_create-vars-file_arguments_to_the_list_subcommand-2e0944e5440c4216.yaml rename tripleoclient/tests/v1/{test_validator.py => tripleo/test_tripleo_validator.py} (100%) diff --git a/releasenotes/notes/Add_parameters_and_create-vars-file_arguments_to_the_list_subcommand-2e0944e5440c4216.yaml b/releasenotes/notes/Add_parameters_and_create-vars-file_arguments_to_the_list_subcommand-2e0944e5440c4216.yaml new file mode 100644 index 000000000..87fe3223d --- /dev/null +++ b/releasenotes/notes/Add_parameters_and_create-vars-file_arguments_to_the_list_subcommand-2e0944e5440c4216.yaml @@ -0,0 +1,6 @@ +--- +features: + - | + The 'openstack tripleo validator list' subcommand can only display all the + available parameters for the validations using the new --parameters + argument and extract them to a file using the new --create-vars-file argument. diff --git a/tripleoclient/tests/test_utils.py b/tripleoclient/tests/test_utils.py index fcfd18769..165c2d4fd 100644 --- a/tripleoclient/tests/test_utils.py +++ b/tripleoclient/tests/test_utils.py @@ -1780,6 +1780,51 @@ class TestAnsibleSymlink(TestCase): mock_cmd.assert_not_called() +class TestGetParamFieldName(TestCase): + def test_with_empty_val_data(self): + input_parameter = {} + expected = "parameters" + + result = utils.get_param_field_name(input_parameter) + self.assertEqual(result, expected) + + def test_with_val_data_and_returns_parameters(self): + input_parameter = {'validations': [ + {'description': 'validation number one', + 'groups': ['prep', 'pre-deployment'], + 'id': 'Validation_Number_One', + 'name': 'Validation Number One', + 'parameters': {}}, + {'description': 'validation number two', + 'groups': ['post-deployment'], + 'id': 'Validation_Number_Two', + 'name': 'Validation Number Two', + 'parameters': {'config_file': "/etc/config.conf"}}, + ]} + expected = "parameters" + + result = utils.get_param_field_name(input_parameter) + self.assertEqual(result, expected) + + def test_with_val_data_and_returns_metadata(self): + input_parameter = {'validations': [ + {'description': 'validation number one', + 'groups': ['prep', 'pre-deployment'], + 'id': 'Validation_Number_One', + 'name': 'Validation Number One', + 'metadata': {}}, + {'description': 'validation number two', + 'groups': ['post-deployment'], + 'id': 'Validation_Number_Two', + 'name': 'Validation Number Two', + 'metadata': {'config_file': "/etc/config.conf"}}, + ]} + expected = "metadata" + + result = utils.get_param_field_name(input_parameter) + self.assertEqual(result, expected) + + class TestParseExtraVars(TestCase): def test_simple_case_text_format(self): input_parameter = ['key1=val1', 'key2=val2 key3=val3'] diff --git a/tripleoclient/tests/v1/test_validator.py b/tripleoclient/tests/v1/tripleo/test_tripleo_validator.py similarity index 100% rename from tripleoclient/tests/v1/test_validator.py rename to tripleoclient/tests/v1/tripleo/test_tripleo_validator.py diff --git a/tripleoclient/utils.py b/tripleoclient/utils.py index accd037a2..183ba06f9 100644 --- a/tripleoclient/utils.py +++ b/tripleoclient/utils.py @@ -1878,14 +1878,55 @@ def _get_from_cfg(cfg, accessor, param, section): return val +def get_param_field_name(validations_data=None): + """Get the current parameters field name in a Dict + + Returns either 'parameters' or 'metadata'. + By Default, it returns 'parameters'. + """ + # TODO(gchamoul): Added for backwards compatibility and will be + # removed for Train release. + if validations_data is None: + validations_data = {} + + if 'metadata' in validations_data.get('validations', [[]])[0]: + return 'metadata' + return 'parameters' + + +def get_validations_parameters(validations_data, + validation_name=None, + groups=None): + if validation_name is None: + validation_name = [] + + if groups is None: + groups = [] + + params = {} + param_field_name = get_param_field_name(validations_data) + + for val in validations_data['validations']: + wanted_validation = False + wanted_group = False + if val.get('id') in validation_name: + wanted_validation = True + + for grp in groups: + if grp in val.get('groups'): + wanted_group = True + + if wanted_validation or wanted_group: + params[val.get('id')] = { + 'parameters': val.get(param_field_name) + } + + return params + + def get_validations_table(validations_data): """Return the validations information as a pretty printed table """ - # TODO(gchamoul): Added for backwards compatibility and will be removed for - # Train Release. - if 'parameters' in validations_data['validations'][0]: - param_field_name = 'parameters' - else: - param_field_name = 'metadata' + param_field_name = get_param_field_name(validations_data) t = PrettyTable(border=True, header=True, padding_width=1) t.title = "TripleO validations" diff --git a/tripleoclient/v1/tripleo_validator.py b/tripleoclient/v1/tripleo_validator.py index bccffd8b7..4612e28ee 100644 --- a/tripleoclient/v1/tripleo_validator.py +++ b/tripleoclient/v1/tripleo_validator.py @@ -68,6 +68,39 @@ class TripleOValidatorList(command.Command): ) parser.add_argument( + '--parameters', + action='store_true', + default=False, + help=_("List available validations parameters") + ) + + parser.add_argument( + '--create-vars-file', + metavar=('[json|yaml]', '/tmp/myvars'), + action='store', + default=[], + nargs=2, + help=_("Create a json or a yaml file " + "containing all the variables " + "available for the validations: " + "[yaml|json] /tmp/myvars") + ) + + ex_group = parser.add_mutually_exclusive_group(required=False) + + ex_group.add_argument( + '--validation-name', + metavar='[,,...]', + action=_CommaListAction, + default=[], + help=_("List specific validations, " + "if more than one validation is required " + "separate the names with commas: " + "--validation-name check-ftype,512e | " + "--validation-name 512e") + ) + + ex_group.add_argument( '--group', metavar='[,,...]', action=_CommaListGroupAction, @@ -81,6 +114,38 @@ class TripleOValidatorList(command.Command): return parser + def _create_variables_file(self, data, varsfile): + msg = (_("The file %s already exists on the filesystem, " + "do you still want to continue [y/N] ")) + + if varsfile[0] not in ['json', 'yaml']: + raise RuntimeError(_('Wrong file type: %s') % varsfile[0]) + else: + LOG.debug(_('Launch variables file creation')) + try: + if os.path.exists(varsfile[-1]): + confirm = oooutils.prompt_user_for_confirmation( + message=msg % varsfile[-1], logger=LOG) + if not confirm: + raise RuntimeError(_("Action not confirmed, exiting")) + + with open(varsfile[-1], 'w') as f: + params = {} + for val_name in data.keys(): + for k, v in data[val_name].get('parameters').items(): + params[k] = v + + if varsfile[0] == 'json': + f.write(oooutils.get_validations_json(params)) + elif varsfile[0] == 'yaml': + f.write(oooutils.get_validations_yaml(params)) + print( + _('The file %s has been created successfully') % + varsfile[-1]) + except Exception as e: + print(_("Creating variables file finished with errors")) + print('Output: {}'.format(e)) + def _run_validator_list(self, parsed_args): clients = self.app.client_manager @@ -91,13 +156,29 @@ class TripleOValidatorList(command.Command): LOG.debug(_('Launch listing the validations')) try: output = validations.list_validations(clients, workflow_input) - if parsed_args.output == 'json': - out = oooutils.get_validations_json({'validations': output}) - elif parsed_args.output == 'yaml': - out = oooutils.get_validations_yaml({'validations': output}) + if parsed_args.parameters: + out = oooutils.get_validations_parameters( + {'validations': output}, + parsed_args.validation_name, + parsed_args.group + ) + + if parsed_args.create_vars_file: + self._create_variables_file(out, + parsed_args.create_vars_file) + else: + print(oooutils.get_validations_json(out)) else: - out = oooutils.get_validations_table({'validations': output}) - print(out) + if parsed_args.output == 'json': + out = oooutils.get_validations_json( + {'validations': output}) + elif parsed_args.output == 'yaml': + out = oooutils.get_validations_yaml( + {'validations': output}) + else: + out = oooutils.get_validations_table( + {'validations': output}) + print(out) except Exception as e: print(_("Validations listing finished with errors")) print('Output: {}'.format(e))