diff --git a/setup.cfg b/setup.cfg index 67934b9b2..a84978897 100644 --- a/setup.cfg +++ b/setup.cfg @@ -106,6 +106,7 @@ openstack.tripleoclient.v1 = undercloud_install = tripleoclient.v1.undercloud:InstallUndercloud undercloud_upgrade = tripleoclient.v1.undercloud:UpgradeUndercloud undercloud_backup = tripleoclient.v1.undercloud_backup:BackupUndercloud + tripleo_validator_list = tripleoclient.v1.tripleo_validator:TripleOValidatorList oslo.config.opts = undercloud_config = tripleoclient.config.undercloud:list_opts standalone_config = tripleoclient.config.standalone:list_opts diff --git a/tripleoclient/constants.py b/tripleoclient/constants.py index 2096c4efc..fdc9af41a 100644 --- a/tripleoclient/constants.py +++ b/tripleoclient/constants.py @@ -77,6 +77,15 @@ ADDITIONAL_ARCHITECTURES = ['ppc64le'] ANSIBLE_VALIDATION_DIR = '/usr/share/openstack-tripleo-validations/validations' +VALIDATION_GROUPS = ['openshift-on-openstack', + 'prep', + 'pre-introspection', + 'pre-deployment', + 'post-deployment', + 'pre-upgrade', + 'post-upgrade'] + + # The path to the local CA certificate installed on the undercloud LOCAL_CACERT_PATH = '/etc/pki/ca-trust/source/anchors/cm-local-ca.pem' diff --git a/tripleoclient/utils.py b/tripleoclient/utils.py index bd4a09b5d..81cee1e67 100644 --- a/tripleoclient/utils.py +++ b/tripleoclient/utils.py @@ -23,6 +23,7 @@ import logging import shutil from six.moves.configparser import ConfigParser +import json import os import os.path import simplejson @@ -31,6 +32,7 @@ import socket import subprocess import sys import tempfile +import textwrap import time import yaml @@ -49,6 +51,8 @@ from six.moves.urllib import request from tripleoclient import constants from tripleoclient import exceptions +from prettytable import PrettyTable + LOG = logging.getLogger(__name__ + ".utils") @@ -1555,6 +1559,40 @@ def get_config_value(cfg, section, option): return val +def get_validations_table(validations_data): + """Return the validations information as a pretty printed table """ + t = PrettyTable(border=True, header=True, padding_width=1) + t.title = "TripleO validations" + t.field_names = ["ID", "Name", "Description", "Groups", "Metadata"] + for validation in validations_data['validations']: + t.add_row([validation['id'], + validation['name'], + "\n".join(textwrap.wrap(validation['description'])), + "\n".join(textwrap.wrap(' '.join(validation['groups']))), + validation['metadata']]) + + t.sortby = "ID" + t.align["ID"] = "l" + t.align["Name"] = "l" + t.align["Description"] = "l" + t.align["Groups"] = "l" + t.align["Metadata"] = "l" + return t + + +def get_validations_json(validations_data): + """Return the validations information as a pretty printed json """ + return json.dumps(validations_data, indent=4, sort_keys=True) + + +def get_validations_yaml(validations_data): + """Return the validations information as a pretty printed yaml """ + return yaml.safe_dump(validations_data, + allow_unicode=True, + default_flow_style=False, + indent=2) + + def ansible_symlink(): # https://bugs.launchpad.net/tripleo/+bug/1812837 python_version = sys.version_info[0] diff --git a/tripleoclient/v1/tripleo_validator.py b/tripleoclient/v1/tripleo_validator.py new file mode 100644 index 000000000..f80a6d980 --- /dev/null +++ b/tripleoclient/v1/tripleo_validator.py @@ -0,0 +1,100 @@ +# Copyright 2019 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +import argparse +import logging + +from osc_lib.command import command +from osc_lib.i18n import _ + +from tripleoclient import constants +from tripleoclient import utils as oooutils + +from tripleoclient.workflows import validations + +LOG = logging.getLogger(__name__ + ".TripleoValidator") + + +class _CommaListGroupAction(argparse.Action): + def __call__(self, parser, namespace, values, option_string=None): + opts = constants.VALIDATION_GROUPS + for value in values.split(','): + if value not in opts: + message = ("Invalid choice: {value} (choose from {choice})" + .format(value=value, + choice=opts)) + raise argparse.ArgumentError(self, message) + setattr(namespace, self.dest, values.split(',')) + + +class TripleOValidatorList(command.Command): + """List the available validations""" + + def get_parser(self, prog_name): + parser = argparse.ArgumentParser( + description=self.get_description(), + prog=prog_name, + add_help=False + ) + + parser.add_argument( + '--output', + action='store', + default='table', + choices=['table', 'json', 'yaml'], + help=_("Change the default output. " + "Defaults to: json " + "i.e. --output json" + " --output yaml") + ) + + parser.add_argument( + '--group', + metavar='[,,...]', + action=_CommaListGroupAction, + default=[], + help=_("List specific group validations, " + "if more than one group is required " + "separate the group names with commas" + "Defaults to: [] " + "i.e. --group pre-upgrade,prep " + " --group openshift-on-openstack") + ) + + return parser + + def _run_validator_list(self, parsed_args): + clients = self.app.client_manager + + workflow_input = { + "group_names": parsed_args.group + } + + 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}) + else: + out = oooutils.get_validations_table({'validations': output}) + print(out) + except Exception as e: + print(_("Validations listing finished with errors")) + print('Output: {}'.format(e)) + + def take_action(self, parsed_args): + self._run_validator_list(parsed_args) diff --git a/tripleoclient/workflows/validations.py b/tripleoclient/workflows/validations.py new file mode 100644 index 000000000..229e917c5 --- /dev/null +++ b/tripleoclient/workflows/validations.py @@ -0,0 +1,35 @@ +# Copyright 2019 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +import pprint + +from tripleoclient.workflows import base + + +def list_validations(clients, workflow_input): + + workflow_client = clients.workflow_engine + tripleoclients = clients.tripleoclient + + with tripleoclients.messaging_websocket() as ws: + execution = base.start_workflow( + workflow_client, + 'tripleo.validations.v1.list', + workflow_input=workflow_input + ) + + for payload in base.wait_for_messages(workflow_client, ws, execution): + if 'message' in payload: + assert payload['status'] == "SUCCESS", pprint.pformat(payload) + return payload['validations']