Add validation config file mechanism
Introduce validation config file. The config default location of the config file will be stored in /etc/validation.cfg The variables precedence will be the following: * user's cli args * config file * default interval values Change-Id: I05c54a43bc0a03878793cca3f51e23f4a8b63a23
This commit is contained in:
parent
c8480cbf80
commit
11488cd88d
@ -20,3 +20,4 @@ Command Options
|
|||||||
~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
.. autoprogram-cliff:: validation.cli
|
.. autoprogram-cliff:: validation.cli
|
||||||
|
:application: validation
|
||||||
|
@ -22,6 +22,10 @@ classifier =
|
|||||||
[files]
|
[files]
|
||||||
packages = validations_libs
|
packages = validations_libs
|
||||||
|
|
||||||
|
data_files =
|
||||||
|
etc =
|
||||||
|
validation.cfg
|
||||||
|
|
||||||
[compile_catalog]
|
[compile_catalog]
|
||||||
directory = validations-libs/locale
|
directory = validations-libs/locale
|
||||||
domain = validations-lib
|
domain = validations-lib
|
||||||
|
63
validation.cfg
Normal file
63
validation.cfg
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
[default]
|
||||||
|
# Default configuration for the Validation Framework
|
||||||
|
# These are mainly CLI parameters which can be set here in order to avoid
|
||||||
|
# to provide the same parameters on each runs.
|
||||||
|
|
||||||
|
# Location where the Validation playbooks are stored.
|
||||||
|
validation_dir = /usr/share/ansible/validation-playbooks
|
||||||
|
|
||||||
|
# Path where the framework is supposed to write logs and results.
|
||||||
|
# Note: this should not be a relative path.
|
||||||
|
# By default the framework log in $HOME/validations.
|
||||||
|
# Uncomment this line according to your prefered location:
|
||||||
|
# validation_log_dir = /usr/share/validations
|
||||||
|
|
||||||
|
# Location where the Ansible Validation Callback, Libraries and Modules are
|
||||||
|
# stored.
|
||||||
|
ansible_base_dir = /usr/share/ansible/
|
||||||
|
|
||||||
|
# Ssh user for the remote access
|
||||||
|
#ssh_user = stack
|
||||||
|
|
||||||
|
# Output log for the Validation results.
|
||||||
|
output_log = output.log
|
||||||
|
|
||||||
|
# Limitation of the number of results to return to the console.
|
||||||
|
history_limit = 15
|
||||||
|
|
||||||
|
fit_width = True
|
||||||
|
|
||||||
|
[ansible_runner]
|
||||||
|
# Ansible Runner configuration parameters.
|
||||||
|
# Here you can set the Runner parameters which will be used by the framework.
|
||||||
|
# Note that only those parameters are supported, any other custom parameters
|
||||||
|
# will be ignored.
|
||||||
|
|
||||||
|
# Verbosity for Ansible
|
||||||
|
verbosity = 5
|
||||||
|
|
||||||
|
# Fact cache directory location and type
|
||||||
|
# fact_cache = /var/log/validations/artifacts/
|
||||||
|
fact_cache_type = jsonfile
|
||||||
|
|
||||||
|
# Inventory for Ansible
|
||||||
|
#inventory = hosts.yaml
|
||||||
|
|
||||||
|
quiet = True
|
||||||
|
rotate_artifacts = 256
|
||||||
|
|
||||||
|
[ansible_environment]
|
||||||
|
# Ansible Environment variables.
|
||||||
|
# You can provide here, all the Ansible configuration variables documented here:
|
||||||
|
# https://docs.ansible.com/ansible/latest/reference_appendices/config.html
|
||||||
|
|
||||||
|
# Here is a set of parameters used by the Validation Framework as example:
|
||||||
|
#ANSIBLE_LOG_PATH = /home/stack/ansible.log
|
||||||
|
#ANSIBLE_REMOTE_USER = stack
|
||||||
|
ANSIBLE_CALLBACK_WHITELIST = validation_stdout,validation_json,profile_tasks
|
||||||
|
ANSIBLE_STDOUT_CALLBACK = validation_stdout
|
||||||
|
|
||||||
|
# Callback settings which are part of Ansible environment variables.
|
||||||
|
# Configuration for HTTP Server callback
|
||||||
|
HTTP_JSON_SERVER = http://localhost
|
||||||
|
HTTP_JSON_PORT = 8080
|
@ -26,6 +26,7 @@ import yaml
|
|||||||
|
|
||||||
from six.moves import configparser
|
from six.moves import configparser
|
||||||
from validations_libs import constants
|
from validations_libs import constants
|
||||||
|
from validations_libs import utils
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__ + ".ansible")
|
LOG = logging.getLogger(__name__ + ".ansible")
|
||||||
|
|
||||||
@ -275,6 +276,17 @@ class Ansible(object):
|
|||||||
else:
|
else:
|
||||||
return env
|
return env
|
||||||
|
|
||||||
|
def _dump_validation_config(self, config, path, filename='validation.cfg'):
|
||||||
|
"""Dump Validation config in artifact directory"""
|
||||||
|
parser = configparser.ConfigParser()
|
||||||
|
for section_key in config.keys():
|
||||||
|
parser.add_section(section_key)
|
||||||
|
for item_key in config[section_key].keys():
|
||||||
|
parser.set(section_key, item_key,
|
||||||
|
str(config[section_key][item_key]))
|
||||||
|
with open('{}/{}'.format(path, filename), 'w') as conf:
|
||||||
|
parser.write(conf)
|
||||||
|
|
||||||
def run(self, playbook, inventory, workdir, playbook_dir=None,
|
def run(self, playbook, inventory, workdir, playbook_dir=None,
|
||||||
connection='smart', output_callback=None,
|
connection='smart', output_callback=None,
|
||||||
base_dir=constants.DEFAULT_VALIDATIONS_BASEDIR,
|
base_dir=constants.DEFAULT_VALIDATIONS_BASEDIR,
|
||||||
@ -283,9 +295,10 @@ class Ansible(object):
|
|||||||
verbosity=0, quiet=False, extra_vars=None,
|
verbosity=0, quiet=False, extra_vars=None,
|
||||||
gathering_policy='smart',
|
gathering_policy='smart',
|
||||||
extra_env_variables=None, parallel_run=False,
|
extra_env_variables=None, parallel_run=False,
|
||||||
callback_whitelist=None, ansible_cfg=None,
|
callback_whitelist=None, ansible_cfg_file=None,
|
||||||
ansible_timeout=30, ansible_artifact_path=None,
|
ansible_timeout=30, ansible_artifact_path=None,
|
||||||
log_path=None, run_async=False, python_interpreter=None):
|
log_path=None, run_async=False, python_interpreter=None,
|
||||||
|
validation_cfg_file=None):
|
||||||
"""Execute one or multiple Ansible playbooks
|
"""Execute one or multiple Ansible playbooks
|
||||||
|
|
||||||
:param playbook: The Absolute path of the Ansible playbook
|
:param playbook: The Absolute path of the Ansible playbook
|
||||||
@ -341,9 +354,10 @@ class Ansible(object):
|
|||||||
Custom output_callback is also whitelisted.
|
Custom output_callback is also whitelisted.
|
||||||
(Defaults to ``None``)
|
(Defaults to ``None``)
|
||||||
:type callback_whitelist: ``list`` or ``string``
|
:type callback_whitelist: ``list`` or ``string``
|
||||||
:param ansible_cfg: Path to an ansible configuration file. One will be
|
:param ansible_cfg_file: Path to an ansible configuration file. One
|
||||||
generated in the artifact path if this option is None.
|
will be generated in the artifact path if
|
||||||
:type ansible_cfg: ``string``
|
this option is None.
|
||||||
|
:type ansible_cfg_file: ``string``
|
||||||
:param ansible_timeout: Timeout for ansible connections.
|
:param ansible_timeout: Timeout for ansible connections.
|
||||||
(Defaults to ``30 minutes``)
|
(Defaults to ``30 minutes``)
|
||||||
:type ansible_timeout: ``integer``
|
:type ansible_timeout: ``integer``
|
||||||
@ -360,6 +374,10 @@ class Ansible(object):
|
|||||||
``auto_silent`` or the default one
|
``auto_silent`` or the default one
|
||||||
``auto_legacy``)
|
``auto_legacy``)
|
||||||
:type python_interpreter: ``string``
|
:type python_interpreter: ``string``
|
||||||
|
:param validation_cfg_file: A dictionary of configuration for
|
||||||
|
Validation loaded from an validation.cfg
|
||||||
|
file.
|
||||||
|
:type validation_cfg_file: ``dict``
|
||||||
|
|
||||||
:return: A ``tuple`` containing the the absolute path of the executed
|
:return: A ``tuple`` containing the the absolute path of the executed
|
||||||
playbook, the return code and the status of the run
|
playbook, the return code and the status of the run
|
||||||
@ -405,16 +423,17 @@ class Ansible(object):
|
|||||||
ansible_timeout, callback_whitelist,
|
ansible_timeout, callback_whitelist,
|
||||||
base_dir, python_interpreter))
|
base_dir, python_interpreter))
|
||||||
|
|
||||||
if 'ANSIBLE_CONFIG' not in env and not ansible_cfg:
|
if 'ANSIBLE_CONFIG' not in env and not ansible_cfg_file:
|
||||||
ansible_cfg = os.path.join(ansible_artifact_path, 'ansible.cfg')
|
ansible_cfg_file = os.path.join(ansible_artifact_path,
|
||||||
config = configparser.ConfigParser()
|
'ansible.cfg')
|
||||||
config.add_section('defaults')
|
ansible_config = configparser.ConfigParser()
|
||||||
config.set('defaults', 'internal_poll_interval', '0.05')
|
ansible_config.add_section('defaults')
|
||||||
with open(ansible_cfg, 'w') as f:
|
ansible_config.set('defaults', 'internal_poll_interval', '0.05')
|
||||||
config.write(f)
|
with open(ansible_cfg_file, 'w') as f:
|
||||||
env['ANSIBLE_CONFIG'] = ansible_cfg
|
ansible_config.write(f)
|
||||||
elif 'ANSIBLE_CONFIG' not in env and ansible_cfg:
|
env['ANSIBLE_CONFIG'] = ansible_cfg_file
|
||||||
env['ANSIBLE_CONFIG'] = ansible_cfg
|
elif 'ANSIBLE_CONFIG' not in env and ansible_cfg_file:
|
||||||
|
env['ANSIBLE_CONFIG'] = ansible_cfg_file
|
||||||
|
|
||||||
if log_path:
|
if log_path:
|
||||||
env['VALIDATIONS_LOG_DIR'] = log_path
|
env['VALIDATIONS_LOG_DIR'] = log_path
|
||||||
@ -434,7 +453,6 @@ class Ansible(object):
|
|||||||
|
|
||||||
if not BACKWARD_COMPAT:
|
if not BACKWARD_COMPAT:
|
||||||
r_opts.update({
|
r_opts.update({
|
||||||
'envvars': envvars,
|
|
||||||
'project_dir': playbook_dir,
|
'project_dir': playbook_dir,
|
||||||
'fact_cache': ansible_artifact_path,
|
'fact_cache': ansible_artifact_path,
|
||||||
'fact_cache_type': 'jsonfile'
|
'fact_cache_type': 'jsonfile'
|
||||||
@ -453,6 +471,17 @@ class Ansible(object):
|
|||||||
|
|
||||||
if parallel_run:
|
if parallel_run:
|
||||||
r_opts['directory_isolation_base_path'] = ansible_artifact_path
|
r_opts['directory_isolation_base_path'] = ansible_artifact_path
|
||||||
|
|
||||||
|
if validation_cfg_file:
|
||||||
|
if 'ansible_runner' in validation_cfg_file.keys():
|
||||||
|
r_opts.update(validation_cfg_file['ansible_runner'])
|
||||||
|
if 'ansible_environment' in validation_cfg_file.keys():
|
||||||
|
envvars.update(validation_cfg_file['ansible_environment'])
|
||||||
|
self._dump_validation_config(validation_cfg_file,
|
||||||
|
ansible_artifact_path)
|
||||||
|
if not BACKWARD_COMPAT:
|
||||||
|
r_opts.update({'envvars': envvars})
|
||||||
|
|
||||||
runner_config = ansible_runner.runner_config.RunnerConfig(**r_opts)
|
runner_config = ansible_runner.runner_config.RunnerConfig(**r_opts)
|
||||||
runner_config.prepare()
|
runner_config.prepare()
|
||||||
runner_config.env['ANSIBLE_STDOUT_CALLBACK'] = \
|
runner_config.env['ANSIBLE_STDOUT_CALLBACK'] = \
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
# 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 sys
|
import sys
|
||||||
|
|
||||||
from cliff.app import App
|
from cliff.app import App
|
||||||
|
@ -14,10 +14,15 @@
|
|||||||
# 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 os
|
||||||
|
|
||||||
from cliff import _argparse
|
from cliff import _argparse
|
||||||
from cliff.command import Command
|
from cliff.command import Command
|
||||||
from cliff.lister import Lister
|
from cliff.lister import Lister
|
||||||
|
from cliff.show import ShowOne
|
||||||
|
|
||||||
|
from validations_libs import constants
|
||||||
|
from validations_libs import utils
|
||||||
|
|
||||||
# Handle backward compatibility for Cliff 2.16.0 in stable/train:
|
# Handle backward compatibility for Cliff 2.16.0 in stable/train:
|
||||||
if hasattr(_argparse, 'SmartHelpFormatter'):
|
if hasattr(_argparse, 'SmartHelpFormatter'):
|
||||||
@ -26,11 +31,50 @@ else:
|
|||||||
from cliff.command import _SmartHelpFormatter as SmartHelpFormatter
|
from cliff.command import _SmartHelpFormatter as SmartHelpFormatter
|
||||||
|
|
||||||
|
|
||||||
|
class Base:
|
||||||
|
"""Base class for CLI arguments management"""
|
||||||
|
config = {}
|
||||||
|
|
||||||
|
def _format_arg(self, parser):
|
||||||
|
"""Format arguments parser"""
|
||||||
|
namespace, argv = parser.parse_known_args()
|
||||||
|
return [arg.lstrip(parser.prefix_chars).replace('-', '_')
|
||||||
|
for arg in argv]
|
||||||
|
|
||||||
|
def set_argument_parser(self, parser, section='default'):
|
||||||
|
""" Set Arguments parser depending of the precedence ordering:
|
||||||
|
* User CLI arguments
|
||||||
|
* Configuration file
|
||||||
|
* Default CLI values
|
||||||
|
"""
|
||||||
|
cli_args = self._format_arg(parser)
|
||||||
|
args, _ = parser.parse_known_args()
|
||||||
|
self.config = utils.load_config(os.path.abspath(args.config))
|
||||||
|
config_args = self.config.get(section, {})
|
||||||
|
for key, value in args._get_kwargs():
|
||||||
|
# matbu: manage the race when user's cli arg is the same than
|
||||||
|
# the parser default value. The user's cli arg will *always*
|
||||||
|
# takes precedence on others.
|
||||||
|
if parser.get_default(key) == value and key in cli_args:
|
||||||
|
try:
|
||||||
|
cli_value = cli_args[cli_args.index(key)+1]
|
||||||
|
config_args.update({key: cli_value})
|
||||||
|
except KeyError:
|
||||||
|
print('Key not found in cli: {}').format(key)
|
||||||
|
elif parser.get_default(key) != value:
|
||||||
|
config_args.update({key: value})
|
||||||
|
elif key not in config_args.keys():
|
||||||
|
config_args.update({key: value})
|
||||||
|
parser.set_defaults(**config_args)
|
||||||
|
return parser
|
||||||
|
|
||||||
|
|
||||||
class BaseCommand(Command):
|
class BaseCommand(Command):
|
||||||
"""Base Command client implementation class"""
|
"""Base Command client implementation class"""
|
||||||
|
|
||||||
def get_parser(self, prog_name):
|
def get_parser(self, prog_name):
|
||||||
"""Argument parser for base command"""
|
"""Argument parser for base command"""
|
||||||
|
self.base = Base()
|
||||||
parser = _argparse.ArgumentParser(
|
parser = _argparse.ArgumentParser(
|
||||||
description=self.get_description(),
|
description=self.get_description(),
|
||||||
epilog=self.get_epilog(),
|
epilog=self.get_epilog(),
|
||||||
@ -40,6 +84,14 @@ class BaseCommand(Command):
|
|||||||
)
|
)
|
||||||
for hook in self._hooks:
|
for hook in self._hooks:
|
||||||
hook.obj.get_parser(parser)
|
hook.obj.get_parser(parser)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
'--config',
|
||||||
|
dest='config',
|
||||||
|
default=utils.find_config_file(),
|
||||||
|
help=("Config file path for Validation.")
|
||||||
|
)
|
||||||
|
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
|
|
||||||
@ -49,6 +101,7 @@ class BaseLister(Lister):
|
|||||||
def get_parser(self, prog_name):
|
def get_parser(self, prog_name):
|
||||||
"""Argument parser for base lister"""
|
"""Argument parser for base lister"""
|
||||||
parser = super(BaseLister, self).get_parser(prog_name)
|
parser = super(BaseLister, self).get_parser(prog_name)
|
||||||
|
self.base = Base()
|
||||||
vf_parser = _argparse.ArgumentParser(
|
vf_parser = _argparse.ArgumentParser(
|
||||||
description=self.get_description(),
|
description=self.get_description(),
|
||||||
epilog=self.get_epilog(),
|
epilog=self.get_epilog(),
|
||||||
@ -60,4 +113,28 @@ class BaseLister(Lister):
|
|||||||
for action in parser._actions:
|
for action in parser._actions:
|
||||||
vf_parser._add_action(action)
|
vf_parser._add_action(action)
|
||||||
|
|
||||||
|
vf_parser.add_argument(
|
||||||
|
'--config',
|
||||||
|
dest='config',
|
||||||
|
default=utils.find_config_file(),
|
||||||
|
help=("Config file path for Validation.")
|
||||||
|
)
|
||||||
|
|
||||||
return vf_parser
|
return vf_parser
|
||||||
|
|
||||||
|
|
||||||
|
class BaseShow(ShowOne):
|
||||||
|
"""Base Show client implementation class"""
|
||||||
|
|
||||||
|
def get_parser(self, parser):
|
||||||
|
"""Argument parser for base show"""
|
||||||
|
parser = super(BaseShow, self).get_parser(parser)
|
||||||
|
self.base = Base()
|
||||||
|
parser.add_argument(
|
||||||
|
'--config',
|
||||||
|
dest='config',
|
||||||
|
default=utils.find_config_file(),
|
||||||
|
help=("Config file path for Validation.")
|
||||||
|
)
|
||||||
|
|
||||||
|
return parser
|
||||||
|
@ -19,8 +19,7 @@ import json
|
|||||||
from validations_libs import constants
|
from validations_libs import constants
|
||||||
from validations_libs.validation_actions import ValidationActions
|
from validations_libs.validation_actions import ValidationActions
|
||||||
from validations_libs.validation_logs import ValidationLogs
|
from validations_libs.validation_logs import ValidationLogs
|
||||||
from validations_libs.cli.base import BaseCommand
|
from validations_libs.cli.base import BaseCommand, BaseLister
|
||||||
from validations_libs.cli.base import BaseLister
|
|
||||||
|
|
||||||
|
|
||||||
class ListHistory(BaseLister):
|
class ListHistory(BaseLister):
|
||||||
@ -46,28 +45,27 @@ class ListHistory(BaseLister):
|
|||||||
default=constants.VALIDATIONS_LOG_BASEDIR,
|
default=constants.VALIDATIONS_LOG_BASEDIR,
|
||||||
help=("Path where the validation log files "
|
help=("Path where the validation log files "
|
||||||
"is located."))
|
"is located."))
|
||||||
return parser
|
# Merge config and CLI args:
|
||||||
|
return self.base.set_argument_parser(parser)
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
|
validation_log_dir = parsed_args.validation_log_dir
|
||||||
|
history_limit = parsed_args.history_limit
|
||||||
|
|
||||||
if parsed_args.history_limit < 1:
|
if history_limit < 1:
|
||||||
raise ValueError(
|
msg = ("Number <n> of the most recent runs must be > 0. "
|
||||||
(
|
"You have provided {}").format(history_limit)
|
||||||
"Number <n> of the most recent runs must be > 0. "
|
raise ValueError(msg)
|
||||||
"You have provided {}").format(
|
|
||||||
parsed_args.history_limit))
|
|
||||||
self.app.LOG.info(
|
self.app.LOG.info(
|
||||||
(
|
("Limiting output to the maximum of "
|
||||||
"Limiting output to the maximum of "
|
"{} last validations.").format(history_limit))
|
||||||
"{} last validations.").format(
|
|
||||||
parsed_args.history_limit))
|
|
||||||
|
|
||||||
actions = ValidationActions()
|
actions = ValidationActions()
|
||||||
|
|
||||||
return actions.show_history(
|
return actions.show_history(
|
||||||
validation_ids=parsed_args.validation,
|
validation_ids=parsed_args.validation,
|
||||||
log_path=parsed_args.validation_log_dir,
|
log_path=parsed_args.validation_log_dir,
|
||||||
history_limit=parsed_args.history_limit)
|
history_limit=history_limit)
|
||||||
|
|
||||||
|
|
||||||
class GetHistory(BaseCommand):
|
class GetHistory(BaseCommand):
|
||||||
@ -88,10 +86,10 @@ class GetHistory(BaseCommand):
|
|||||||
default=constants.VALIDATIONS_LOG_BASEDIR,
|
default=constants.VALIDATIONS_LOG_BASEDIR,
|
||||||
help=("Path where the validation log files "
|
help=("Path where the validation log files "
|
||||||
"is located."))
|
"is located."))
|
||||||
return parser
|
# Merge config and CLI args:
|
||||||
|
return self.base.set_argument_parser(parser)
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
|
|
||||||
self.app.LOG.debug(
|
self.app.LOG.debug(
|
||||||
(
|
(
|
||||||
"Obtaining information about the validation run {}\n"
|
"Obtaining information about the validation run {}\n"
|
||||||
|
@ -14,14 +14,13 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
from cliff.lister import Lister
|
|
||||||
|
|
||||||
from validations_libs.validation_actions import ValidationActions
|
from validations_libs.validation_actions import ValidationActions
|
||||||
from validations_libs import constants
|
from validations_libs import constants
|
||||||
|
from validations_libs.cli.base import BaseLister
|
||||||
from validations_libs.cli.parseractions import CommaListAction
|
from validations_libs.cli.parseractions import CommaListAction
|
||||||
|
|
||||||
|
|
||||||
class ValidationList(Lister):
|
class ValidationList(BaseLister):
|
||||||
"""List the Validations Catalog"""
|
"""List the Validations Catalog"""
|
||||||
|
|
||||||
def get_parser(self, parser):
|
def get_parser(self, parser):
|
||||||
@ -52,7 +51,8 @@ class ValidationList(Lister):
|
|||||||
default=constants.ANSIBLE_VALIDATION_DIR,
|
default=constants.ANSIBLE_VALIDATION_DIR,
|
||||||
help=("Path where the validation playbooks "
|
help=("Path where the validation playbooks "
|
||||||
"are located."))
|
"are located."))
|
||||||
return parser
|
# Merge config and CLI args:
|
||||||
|
return self.base.set_argument_parser(parser)
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
"""Take validation action"""
|
"""Take validation action"""
|
||||||
@ -61,6 +61,7 @@ class ValidationList(Lister):
|
|||||||
category = parsed_args.category
|
category = parsed_args.category
|
||||||
product = parsed_args.product
|
product = parsed_args.product
|
||||||
validation_dir = parsed_args.validation_dir
|
validation_dir = parsed_args.validation_dir
|
||||||
|
group = parsed_args.group
|
||||||
|
|
||||||
v_actions = ValidationActions(validation_path=validation_dir)
|
v_actions = ValidationActions(validation_path=validation_dir)
|
||||||
return (v_actions.list_validations(groups=group,
|
return (v_actions.list_validations(groups=group,
|
||||||
|
@ -156,17 +156,23 @@ class Run(BaseCommand):
|
|||||||
"if more than one product is required "
|
"if more than one product is required "
|
||||||
"separate the product names with commas."))
|
"separate the product names with commas."))
|
||||||
|
|
||||||
|
if self.app:
|
||||||
|
# Merge config and CLI args:
|
||||||
|
return self.base.set_argument_parser(parser)
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
"""Take validation action"""
|
"""Take validation action"""
|
||||||
v_actions = ValidationActions(
|
# Get config:
|
||||||
validation_path=parsed_args.validation_dir)
|
config = self.base.config
|
||||||
|
|
||||||
|
v_actions = ValidationActions(parsed_args.validation_dir)
|
||||||
# Ansible execution should be quiet while using the validations_json
|
# Ansible execution should be quiet while using the validations_json
|
||||||
# default callback and be verbose while passing ANSIBLE_SDTOUT_CALLBACK
|
# default callback and be verbose while passing ANSIBLE_SDTOUT_CALLBACK
|
||||||
# environment variable to Ansible through the --extra-env-vars argument
|
# environment variable to Ansible through the --extra-env-vars argument
|
||||||
quiet_mode = True
|
runner_config = (config.get('ansible_runner', {})
|
||||||
|
if isinstance(config, dict) else {})
|
||||||
|
quiet_mode = runner_config.get('quiet', True)
|
||||||
extra_env_vars = parsed_args.extra_env_vars
|
extra_env_vars = parsed_args.extra_env_vars
|
||||||
if extra_env_vars:
|
if extra_env_vars:
|
||||||
if "ANSIBLE_STDOUT_CALLBACK" in extra_env_vars.keys():
|
if "ANSIBLE_STDOUT_CALLBACK" in extra_env_vars.keys():
|
||||||
@ -178,7 +184,8 @@ class Run(BaseCommand):
|
|||||||
"Loading extra vars file {}".format(
|
"Loading extra vars file {}".format(
|
||||||
parsed_args.extra_vars_file))
|
parsed_args.extra_vars_file))
|
||||||
|
|
||||||
extra_vars = common.read_extra_vars_file(parsed_args.extra_vars_file)
|
extra_vars = common.read_extra_vars_file(
|
||||||
|
parsed_args.extra_vars_file)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
results = v_actions.run_validations(
|
results = v_actions.run_validations(
|
||||||
@ -195,8 +202,8 @@ class Run(BaseCommand):
|
|||||||
python_interpreter=parsed_args.python_interpreter,
|
python_interpreter=parsed_args.python_interpreter,
|
||||||
quiet=quiet_mode,
|
quiet=quiet_mode,
|
||||||
ssh_user=parsed_args.ssh_user,
|
ssh_user=parsed_args.ssh_user,
|
||||||
log_path=parsed_args.validation_log_dir
|
log_path=parsed_args.validation_log_dir,
|
||||||
)
|
validation_config=config)
|
||||||
except RuntimeError as e:
|
except RuntimeError as e:
|
||||||
raise RuntimeError(e)
|
raise RuntimeError(e)
|
||||||
|
|
||||||
|
@ -14,15 +14,13 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
from cliff.show import ShowOne
|
|
||||||
from cliff.lister import Lister
|
|
||||||
|
|
||||||
from validations_libs.validation_actions import ValidationActions
|
from validations_libs.validation_actions import ValidationActions
|
||||||
from validations_libs import constants
|
from validations_libs import constants
|
||||||
from validations_libs.cli.parseractions import CommaListAction
|
from validations_libs.cli.parseractions import CommaListAction
|
||||||
|
from validations_libs.cli.base import BaseShow, BaseLister
|
||||||
|
|
||||||
|
|
||||||
class Show(ShowOne):
|
class Show(BaseShow):
|
||||||
"""Show detailed informations about a Validation"""
|
"""Show detailed informations about a Validation"""
|
||||||
|
|
||||||
def get_parser(self, parser):
|
def get_parser(self, parser):
|
||||||
@ -36,7 +34,8 @@ class Show(ShowOne):
|
|||||||
metavar="<validation>",
|
metavar="<validation>",
|
||||||
type=str,
|
type=str,
|
||||||
help="Show a specific validation.")
|
help="Show a specific validation.")
|
||||||
return parser
|
# Merge config and CLI args:
|
||||||
|
return self.base.set_argument_parser(parser)
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
"""Take validation action"""
|
"""Take validation action"""
|
||||||
@ -51,7 +50,7 @@ class Show(ShowOne):
|
|||||||
return data.keys(), data.values()
|
return data.keys(), data.values()
|
||||||
|
|
||||||
|
|
||||||
class ShowGroup(Lister):
|
class ShowGroup(BaseLister):
|
||||||
"""Show detailed informations about Validation Groups"""
|
"""Show detailed informations about Validation Groups"""
|
||||||
|
|
||||||
def get_parser(self, parser):
|
def get_parser(self, parser):
|
||||||
@ -63,7 +62,8 @@ class ShowGroup(Lister):
|
|||||||
help=("Path where the validation playbooks "
|
help=("Path where the validation playbooks "
|
||||||
"are located."))
|
"are located."))
|
||||||
|
|
||||||
return parser
|
# Merge config and CLI args:
|
||||||
|
return self.base.set_argument_parser(parser)
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
"""Take validation action"""
|
"""Take validation action"""
|
||||||
@ -72,7 +72,7 @@ class ShowGroup(Lister):
|
|||||||
return v_actions.group_information(constants.VALIDATION_GROUPS_INFO)
|
return v_actions.group_information(constants.VALIDATION_GROUPS_INFO)
|
||||||
|
|
||||||
|
|
||||||
class ShowParameter(ShowOne):
|
class ShowParameter(BaseShow):
|
||||||
"""Show Validation(s) parameter(s)
|
"""Show Validation(s) parameter(s)
|
||||||
|
|
||||||
Display Validation(s) Parameter(s) which could be overriden during an
|
Display Validation(s) Parameter(s) which could be overriden during an
|
||||||
@ -147,11 +147,13 @@ class ShowParameter(ShowOne):
|
|||||||
help=("Print representation of the validation. "
|
help=("Print representation of the validation. "
|
||||||
"The choices of the output format is json,yaml. ")
|
"The choices of the output format is json,yaml. ")
|
||||||
)
|
)
|
||||||
|
# Merge config and CLI args:
|
||||||
return parser
|
return self.base.set_argument_parser(parser)
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
v_actions = ValidationActions(parsed_args.validation_dir)
|
|
||||||
|
validation_dir = parsed_args.validation_dir
|
||||||
|
v_actions = ValidationActions(validation_dir)
|
||||||
params = v_actions.show_validations_parameters(
|
params = v_actions.show_validations_parameters(
|
||||||
validations=parsed_args.validation_name,
|
validations=parsed_args.validation_name,
|
||||||
groups=parsed_args.group,
|
groups=parsed_args.group,
|
||||||
|
@ -38,3 +38,7 @@ VALIDATIONS_LOG_BASEDIR = os.path.expanduser('~/validations')
|
|||||||
VALIDATION_ANSIBLE_ARTIFACT_PATH = os.path.join(
|
VALIDATION_ANSIBLE_ARTIFACT_PATH = os.path.join(
|
||||||
VALIDATIONS_LOG_BASEDIR,
|
VALIDATIONS_LOG_BASEDIR,
|
||||||
'artifacts')
|
'artifacts')
|
||||||
|
|
||||||
|
ANSIBLE_RUNNER_CONFIG_PARAMETERS = ['verbosity', 'extravars', 'fact_cache',
|
||||||
|
'fact_cache_type', 'inventory', 'playbook',
|
||||||
|
'project_dir', 'quiet', 'rotate_artifacts']
|
||||||
|
@ -12,17 +12,26 @@
|
|||||||
# 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 sys
|
||||||
|
|
||||||
from unittest import TestCase
|
from unittest import TestCase
|
||||||
|
|
||||||
from validations_libs.cli import app
|
from validations_libs.cli import app
|
||||||
|
from validations_libs.cli import base
|
||||||
|
from validations_libs import utils
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
from unittest import mock
|
||||||
|
except ImportError:
|
||||||
|
import mock
|
||||||
|
|
||||||
|
|
||||||
class BaseCommand(TestCase):
|
class BaseCommand(TestCase):
|
||||||
|
|
||||||
def check_parser(self, cmd, args, verify_args):
|
def check_parser(self, cmd, args, verify_args):
|
||||||
cmd_parser = cmd.get_parser('check_parser')
|
|
||||||
try:
|
try:
|
||||||
|
cmd_parser = cmd.get_parser('check_parser')
|
||||||
parsed_args = cmd_parser.parse_args(args)
|
parsed_args = cmd_parser.parse_args(args)
|
||||||
except SystemExit:
|
except SystemExit:
|
||||||
raise Exception("Argument parse failed")
|
raise Exception("Argument parse failed")
|
||||||
@ -35,8 +44,15 @@ class BaseCommand(TestCase):
|
|||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(BaseCommand, self).setUp()
|
super(BaseCommand, self).setUp()
|
||||||
|
self._set_args([])
|
||||||
self.app = app.ValidationCliApp()
|
self.app = app.ValidationCliApp()
|
||||||
|
|
||||||
|
def _set_args(self, args):
|
||||||
|
sys.argv = sys.argv[:1]
|
||||||
|
sys.argv.extend(args)
|
||||||
|
return args
|
||||||
|
|
||||||
|
|
||||||
KEYVALUEACTION_VALUES = {
|
KEYVALUEACTION_VALUES = {
|
||||||
'valid': 'foo=bar',
|
'valid': 'foo=bar',
|
||||||
'invalid_noeq': 'foo>bar',
|
'invalid_noeq': 'foo>bar',
|
||||||
|
115
validations_libs/tests/cli/test_app.py
Normal file
115
validations_libs/tests/cli/test_app.py
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
# Copyright 2021 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 sys
|
||||||
|
|
||||||
|
try:
|
||||||
|
from unittest import mock
|
||||||
|
except ImportError:
|
||||||
|
import mock
|
||||||
|
from unittest import TestCase
|
||||||
|
|
||||||
|
from validations_libs.cli import app
|
||||||
|
from validations_libs.cli import lister
|
||||||
|
from validations_libs.cli import history
|
||||||
|
|
||||||
|
|
||||||
|
class TestArgApp(TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestArgApp, self).setUp()
|
||||||
|
self._set_args([])
|
||||||
|
self.app = app.ValidationCliApp()
|
||||||
|
|
||||||
|
def _set_args(self, args):
|
||||||
|
sys.argv = sys.argv[:1]
|
||||||
|
sys.argv.extend(args)
|
||||||
|
return args
|
||||||
|
|
||||||
|
def test_validation_dir_config_cli(self):
|
||||||
|
args = ['--validation-dir', 'foo']
|
||||||
|
self._set_args(args)
|
||||||
|
cmd = lister.ValidationList(self.app, None)
|
||||||
|
parser = cmd.get_parser('fake')
|
||||||
|
parsed_args = parser.parse_args(args)
|
||||||
|
self.assertEqual('foo', parsed_args.validation_dir)
|
||||||
|
|
||||||
|
@mock.patch('validations_libs.constants.ANSIBLE_VALIDATION_DIR', 'bar')
|
||||||
|
@mock.patch('validations_libs.utils.find_config_file',
|
||||||
|
return_value='validation.cfg')
|
||||||
|
def test_validation_dir_config_no_cli(self, mock_config):
|
||||||
|
args = []
|
||||||
|
self._set_args(args)
|
||||||
|
cmd = lister.ValidationList(self.app, None)
|
||||||
|
parser = cmd.get_parser('fake')
|
||||||
|
parsed_args = parser.parse_args(args)
|
||||||
|
self.assertEqual('/usr/share/ansible/validation-playbooks',
|
||||||
|
parsed_args.validation_dir)
|
||||||
|
|
||||||
|
@mock.patch('validations_libs.constants.ANSIBLE_VALIDATION_DIR', 'bar')
|
||||||
|
@mock.patch('validations_libs.utils.find_config_file',
|
||||||
|
return_value='/etc/validation.cfg')
|
||||||
|
def test_validation_dir_config_no_cli_no_config(self, mock_config):
|
||||||
|
args = []
|
||||||
|
self._set_args(args)
|
||||||
|
cmd = lister.ValidationList(self.app, None)
|
||||||
|
parser = cmd.get_parser('fake')
|
||||||
|
parsed_args = parser.parse_args(args)
|
||||||
|
self.assertEqual('bar', parsed_args.validation_dir)
|
||||||
|
|
||||||
|
@mock.patch('validations_libs.constants.ANSIBLE_VALIDATION_DIR',
|
||||||
|
'/usr/share/ansible/validation-playbooks')
|
||||||
|
@mock.patch('validations_libs.utils.find_config_file',
|
||||||
|
return_value='validation.cfg')
|
||||||
|
def test_validation_dir_config_no_cli_same_consts(self, mock_config):
|
||||||
|
args = []
|
||||||
|
self._set_args(args)
|
||||||
|
cmd = lister.ValidationList(self.app, None)
|
||||||
|
parser = cmd.get_parser('fake')
|
||||||
|
parsed_args = parser.parse_args(args)
|
||||||
|
self.assertEqual('/usr/share/ansible/validation-playbooks',
|
||||||
|
parsed_args.validation_dir)
|
||||||
|
|
||||||
|
def test_get_history_cli_arg(self):
|
||||||
|
args = ['123', '--validation-log-dir', '/foo/log/dir']
|
||||||
|
self._set_args(args)
|
||||||
|
cmd = history.GetHistory(self.app, None)
|
||||||
|
parser = cmd.get_parser('fake')
|
||||||
|
parsed_args = parser.parse_args(args)
|
||||||
|
self.assertEqual('/foo/log/dir',
|
||||||
|
parsed_args.validation_log_dir)
|
||||||
|
|
||||||
|
@mock.patch('validations_libs.utils.find_config_file',
|
||||||
|
return_value='validation.cfg')
|
||||||
|
def test_get_history_cli_arg_and_config_file(self, mock_config):
|
||||||
|
args = ['123', '--validation-log-dir', '/foo/log/dir']
|
||||||
|
self._set_args(args)
|
||||||
|
cmd = history.GetHistory(self.app, None)
|
||||||
|
parser = cmd.get_parser('fake')
|
||||||
|
parsed_args = parser.parse_args(args)
|
||||||
|
self.assertEqual('/foo/log/dir',
|
||||||
|
parsed_args.validation_log_dir)
|
||||||
|
|
||||||
|
@mock.patch('validations_libs.constants.VALIDATIONS_LOG_BASEDIR',
|
||||||
|
'/home/foo/validations')
|
||||||
|
@mock.patch('validations_libs.utils.find_config_file',
|
||||||
|
return_value='validation.cfg')
|
||||||
|
def test_get_history_no_cli_arg_and_config_file(self, mock_config):
|
||||||
|
args = ['123']
|
||||||
|
self._set_args(args)
|
||||||
|
cmd = history.GetHistory(self.app, None)
|
||||||
|
parser = cmd.get_parser('fake')
|
||||||
|
parsed_args = parser.parse_args(args)
|
||||||
|
self.assertEqual('/home/foo/validations',
|
||||||
|
parsed_args.validation_log_dir)
|
94
validations_libs/tests/cli/test_base.py
Normal file
94
validations_libs/tests/cli/test_base.py
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
# Copyright 2021 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
try:
|
||||||
|
from unittest import mock
|
||||||
|
except ImportError:
|
||||||
|
import mock
|
||||||
|
from unittest import TestCase
|
||||||
|
|
||||||
|
from validations_libs.cli import lister
|
||||||
|
from validations_libs.cli import base
|
||||||
|
from validations_libs.tests import fakes
|
||||||
|
from validations_libs.tests.cli.fakes import BaseCommand
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
|
||||||
|
class TestArgParse(argparse.ArgumentParser):
|
||||||
|
|
||||||
|
config = 'foo'
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super(TestArgParse, self).__init__()
|
||||||
|
|
||||||
|
|
||||||
|
class TestBase(BaseCommand):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestBase, self).setUp()
|
||||||
|
self.cmd = lister.ValidationList(self.app, None)
|
||||||
|
self.base = base.Base()
|
||||||
|
|
||||||
|
@mock.patch('argparse.ArgumentParser.parse_known_args',
|
||||||
|
return_value=(TestArgParse(), ['foo-bar']))
|
||||||
|
@mock.patch('os.path.abspath', return_value='/foo')
|
||||||
|
@mock.patch('validations_libs.utils.load_config',
|
||||||
|
return_value=fakes.DEFAULT_CONFIG)
|
||||||
|
def test_config_args(self, mock_config, mock_path, mock_argv):
|
||||||
|
cmd_parser = self.cmd.get_parser('check_parser')
|
||||||
|
|
||||||
|
self.assertEqual(['foo_bar'], self.base._format_arg(cmd_parser))
|
||||||
|
|
||||||
|
@mock.patch('os.path.abspath', return_value='/foo')
|
||||||
|
@mock.patch('validations_libs.utils.load_config',
|
||||||
|
return_value=fakes.DEFAULT_CONFIG)
|
||||||
|
def test_argument_parser_cli_choice(self, mock_load, mock_path):
|
||||||
|
arglist = ['--validation-dir', 'foo', '--config', 'validation.cfg']
|
||||||
|
verifylist = [('validation_dir', 'foo')]
|
||||||
|
self._set_args(arglist)
|
||||||
|
cmd_parser = self.cmd.get_parser('check_parser')
|
||||||
|
parser = self.base.set_argument_parser(cmd_parser)
|
||||||
|
|
||||||
|
self.assertEqual(fakes.DEFAULT_CONFIG, self.base.config)
|
||||||
|
self.assertEqual(parser.get_default('validation_dir'), 'foo')
|
||||||
|
|
||||||
|
@mock.patch('os.path.abspath', return_value='/foo')
|
||||||
|
@mock.patch('validations_libs.utils.load_config',
|
||||||
|
return_value=fakes.DEFAULT_CONFIG)
|
||||||
|
def test_argument_parser_config_choice(self, mock_load, mock_path):
|
||||||
|
arglist = []
|
||||||
|
verifylist = []
|
||||||
|
self._set_args(arglist)
|
||||||
|
cmd_parser = self.cmd.get_parser('check_parser')
|
||||||
|
parser = self.base.set_argument_parser(cmd_parser)
|
||||||
|
|
||||||
|
self.assertEqual(fakes.DEFAULT_CONFIG, self.base.config)
|
||||||
|
self.assertEqual(parser.get_default('validation_dir'),
|
||||||
|
'/usr/share/ansible/validation-playbooks')
|
||||||
|
|
||||||
|
@mock.patch('os.path.abspath', return_value='/foo')
|
||||||
|
@mock.patch('validations_libs.utils.load_config',
|
||||||
|
return_value={})
|
||||||
|
def test_argument_parser_constant_choice(self, mock_load, mock_path):
|
||||||
|
arglist = []
|
||||||
|
verifylist = []
|
||||||
|
self._set_args(arglist)
|
||||||
|
cmd_parser = self.cmd.get_parser('check_parser')
|
||||||
|
parser = self.base.set_argument_parser(cmd_parser)
|
||||||
|
|
||||||
|
self.assertEqual({}, self.base.config)
|
||||||
|
self.assertEqual(parser.get_default('validation_dir'),
|
||||||
|
'/usr/share/ansible/validation-playbooks')
|
@ -34,6 +34,7 @@ class TestListHistory(BaseCommand):
|
|||||||
arglist = ['--validation-log-dir', '/foo/log/dir']
|
arglist = ['--validation-log-dir', '/foo/log/dir']
|
||||||
verifylist = [('validation_log_dir', '/foo/log/dir')]
|
verifylist = [('validation_log_dir', '/foo/log/dir')]
|
||||||
|
|
||||||
|
self._set_args(arglist)
|
||||||
col = ('UUID', 'Validations', 'Status', 'Execution at', 'Duration')
|
col = ('UUID', 'Validations', 'Status', 'Execution at', 'Duration')
|
||||||
values = [('008886df-d297-1eaa-2a74-000000000008',
|
values = [('008886df-d297-1eaa-2a74-000000000008',
|
||||||
'512e', 'PASSED',
|
'512e', 'PASSED',
|
||||||
@ -44,6 +45,33 @@ class TestListHistory(BaseCommand):
|
|||||||
result = self.cmd.take_action(parsed_args)
|
result = self.cmd.take_action(parsed_args)
|
||||||
self.assertEqual(result, (col, values))
|
self.assertEqual(result, (col, values))
|
||||||
|
|
||||||
|
@mock.patch('validations_libs.validation_actions.ValidationActions.'
|
||||||
|
'show_history')
|
||||||
|
@mock.patch('validations_libs.utils.load_config',
|
||||||
|
return_value=fakes.DEFAULT_CONFIG)
|
||||||
|
def test_list_history_limit_with_config(self, mock_config, mock_history):
|
||||||
|
arglist = ['--validation-log-dir', '/foo/log/dir']
|
||||||
|
verifylist = [('validation_log_dir', '/foo/log/dir')]
|
||||||
|
self._set_args(arglist)
|
||||||
|
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
self.assertEqual(parsed_args.history_limit, 15)
|
||||||
|
|
||||||
|
@mock.patch('validations_libs.validation_actions.ValidationActions.'
|
||||||
|
'show_history')
|
||||||
|
@mock.patch('validations_libs.utils.load_config',
|
||||||
|
return_value=fakes.WRONG_HISTORY_CONFIG)
|
||||||
|
def test_list_history_limit_with_wrong_config(self, mock_config,
|
||||||
|
mock_history):
|
||||||
|
arglist = ['--validation-log-dir', '/foo/log/dir']
|
||||||
|
verifylist = [('validation_log_dir', '/foo/log/dir')]
|
||||||
|
self._set_args(arglist)
|
||||||
|
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
self.assertEqual(parsed_args.history_limit, 0)
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
self.assertRaises(ValueError, self.cmd.take_action, parsed_args)
|
||||||
|
|
||||||
|
|
||||||
class TestGetHistory(BaseCommand):
|
class TestGetHistory(BaseCommand):
|
||||||
|
|
||||||
@ -57,6 +85,7 @@ class TestGetHistory(BaseCommand):
|
|||||||
def test_get_history(self, mock_logs):
|
def test_get_history(self, mock_logs):
|
||||||
arglist = ['123']
|
arglist = ['123']
|
||||||
verifylist = [('uuid', '123')]
|
verifylist = [('uuid', '123')]
|
||||||
|
self._set_args(arglist)
|
||||||
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
self.cmd.take_action(parsed_args)
|
self.cmd.take_action(parsed_args)
|
||||||
@ -68,6 +97,7 @@ class TestGetHistory(BaseCommand):
|
|||||||
arglist = ['123', '--validation-log-dir', '/foo/log/dir']
|
arglist = ['123', '--validation-log-dir', '/foo/log/dir']
|
||||||
verifylist = [('uuid', '123'), ('validation_log_dir', '/foo/log/dir')]
|
verifylist = [('uuid', '123'), ('validation_log_dir', '/foo/log/dir')]
|
||||||
|
|
||||||
|
self._set_args(arglist)
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
self.cmd.take_action(parsed_args)
|
self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
@ -78,5 +108,6 @@ class TestGetHistory(BaseCommand):
|
|||||||
arglist = ['123', '--full']
|
arglist = ['123', '--full']
|
||||||
verifylist = [('uuid', '123'), ('full', True)]
|
verifylist = [('uuid', '123'), ('full', True)]
|
||||||
|
|
||||||
|
self._set_args(arglist)
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
self.cmd.take_action(parsed_args)
|
self.cmd.take_action(parsed_args)
|
||||||
|
@ -34,24 +34,25 @@ class TestRun(BaseCommand):
|
|||||||
'run_validations',
|
'run_validations',
|
||||||
return_value=None)
|
return_value=None)
|
||||||
def test_run_command_return_none(self, mock_run):
|
def test_run_command_return_none(self, mock_run):
|
||||||
arglist = ['--validation', 'foo']
|
args = self._set_args(['--validation', 'foo'])
|
||||||
verifylist = [('validation_name', ['foo'])]
|
verifylist = [('validation_name', ['foo'])]
|
||||||
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
parsed_args = self.check_parser(self.cmd, args, verifylist)
|
||||||
self.assertRaises(RuntimeError, self.cmd.take_action, parsed_args)
|
self.assertRaises(RuntimeError, self.cmd.take_action, parsed_args)
|
||||||
|
|
||||||
@mock.patch('validations_libs.validation_actions.ValidationActions.'
|
@mock.patch('validations_libs.validation_actions.ValidationActions.'
|
||||||
'run_validations',
|
'run_validations',
|
||||||
return_value=copy.deepcopy(fakes.FAKE_SUCCESS_RUN))
|
return_value=copy.deepcopy(fakes.FAKE_SUCCESS_RUN))
|
||||||
def test_run_command_success(self, mock_run):
|
def test_run_command_success(self, mock_run):
|
||||||
arglist = ['--validation', 'foo']
|
args = self._set_args(['--validation', 'foo'])
|
||||||
verifylist = [('validation_name', ['foo'])]
|
verifylist = [('validation_name', ['foo'])]
|
||||||
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
parsed_args = self.check_parser(self.cmd, args, verifylist)
|
||||||
self.cmd.take_action(parsed_args)
|
self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
def test_run_command_exclusive_group(self):
|
def test_run_command_exclusive_group(self):
|
||||||
arglist = ['--validation', 'foo', '--group', 'bar']
|
arglist = ['--validation', 'foo', '--group', 'bar']
|
||||||
|
self._set_args(arglist)
|
||||||
verifylist = [('validation_name', ['foo'], 'group', 'bar')]
|
verifylist = [('validation_name', ['foo'], 'group', 'bar')]
|
||||||
|
|
||||||
self.assertRaises(Exception, self.check_parser, self.cmd,
|
self.assertRaises(Exception, self.check_parser, self.cmd,
|
||||||
@ -64,8 +65,9 @@ class TestRun(BaseCommand):
|
|||||||
@mock.patch('validations_libs.validation_actions.ValidationActions.'
|
@mock.patch('validations_libs.validation_actions.ValidationActions.'
|
||||||
'run_validations',
|
'run_validations',
|
||||||
return_value=copy.deepcopy(fakes.FAKE_SUCCESS_RUN))
|
return_value=copy.deepcopy(fakes.FAKE_SUCCESS_RUN))
|
||||||
def test_run_command_extra_vars(self, mock_run, mock_user, mock_print,
|
@mock.patch('validations_libs.utils.load_config', return_value={})
|
||||||
mock_log_dir):
|
def test_run_command_extra_vars(self, mock_config, mock_run,
|
||||||
|
mock_user, mock_print, mock_log_dir):
|
||||||
run_called_args = {
|
run_called_args = {
|
||||||
'inventory': 'localhost',
|
'inventory': 'localhost',
|
||||||
'limit_hosts': None,
|
'limit_hosts': None,
|
||||||
@ -80,13 +82,15 @@ class TestRun(BaseCommand):
|
|||||||
'python_interpreter': sys.executable,
|
'python_interpreter': sys.executable,
|
||||||
'quiet': True,
|
'quiet': True,
|
||||||
'ssh_user': 'doe',
|
'ssh_user': 'doe',
|
||||||
'log_path': mock_log_dir}
|
'log_path': mock_log_dir,
|
||||||
|
'validation_config': {}
|
||||||
|
}
|
||||||
|
|
||||||
arglist = ['--validation', 'foo',
|
arglist = ['--validation', 'foo',
|
||||||
'--extra-vars', 'key=value']
|
'--extra-vars', 'key=value']
|
||||||
verifylist = [('validation_name', ['foo']),
|
verifylist = [('validation_name', ['foo']),
|
||||||
('extra_vars', {'key': 'value'})]
|
('extra_vars', {'key': 'value'})]
|
||||||
|
self._set_args(arglist)
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
self.cmd.take_action(parsed_args)
|
self.cmd.take_action(parsed_args)
|
||||||
mock_run.assert_called_with(**run_called_args)
|
mock_run.assert_called_with(**run_called_args)
|
||||||
@ -98,8 +102,10 @@ class TestRun(BaseCommand):
|
|||||||
@mock.patch('validations_libs.validation_actions.ValidationActions.'
|
@mock.patch('validations_libs.validation_actions.ValidationActions.'
|
||||||
'run_validations',
|
'run_validations',
|
||||||
return_value=copy.deepcopy(fakes.FAKE_SUCCESS_RUN))
|
return_value=copy.deepcopy(fakes.FAKE_SUCCESS_RUN))
|
||||||
def test_run_command_extra_vars_twice(self, mock_run, mock_user,
|
@mock.patch('validations_libs.utils.load_config', return_value={})
|
||||||
mock_print, mock_log_dir):
|
def test_run_command_extra_vars_twice(self, mock_config,
|
||||||
|
mock_run, mock_user, mock_print,
|
||||||
|
mock_log_dir):
|
||||||
run_called_args = {
|
run_called_args = {
|
||||||
'inventory': 'localhost',
|
'inventory': 'localhost',
|
||||||
'limit_hosts': None,
|
'limit_hosts': None,
|
||||||
@ -114,14 +120,16 @@ class TestRun(BaseCommand):
|
|||||||
'python_interpreter': sys.executable,
|
'python_interpreter': sys.executable,
|
||||||
'quiet': True,
|
'quiet': True,
|
||||||
'ssh_user': 'doe',
|
'ssh_user': 'doe',
|
||||||
'log_path': mock_log_dir}
|
'log_path': mock_log_dir,
|
||||||
|
'validation_config': {}
|
||||||
|
}
|
||||||
|
|
||||||
arglist = ['--validation', 'foo',
|
arglist = ['--validation', 'foo',
|
||||||
'--extra-vars', 'key=value1',
|
'--extra-vars', 'key=value1',
|
||||||
'--extra-vars', 'key=value2']
|
'--extra-vars', 'key=value2']
|
||||||
verifylist = [('validation_name', ['foo']),
|
verifylist = [('validation_name', ['foo']),
|
||||||
('extra_vars', {'key': 'value2'})]
|
('extra_vars', {'key': 'value2'})]
|
||||||
|
self._set_args(arglist)
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
self.cmd.take_action(parsed_args)
|
self.cmd.take_action(parsed_args)
|
||||||
mock_run.assert_called_with(**run_called_args)
|
mock_run.assert_called_with(**run_called_args)
|
||||||
@ -144,7 +152,9 @@ class TestRun(BaseCommand):
|
|||||||
@mock.patch('validations_libs.validation_actions.ValidationActions.'
|
@mock.patch('validations_libs.validation_actions.ValidationActions.'
|
||||||
'run_validations',
|
'run_validations',
|
||||||
return_value=copy.deepcopy(fakes.FAKE_SUCCESS_RUN))
|
return_value=copy.deepcopy(fakes.FAKE_SUCCESS_RUN))
|
||||||
def test_run_command_extra_vars_file(self, mock_run, mock_user, mock_open,
|
@mock.patch('validations_libs.utils.load_config', return_value={})
|
||||||
|
def test_run_command_extra_vars_file(self, mock_config, mock_run,
|
||||||
|
mock_user, mock_open,
|
||||||
mock_yaml, mock_log_dir):
|
mock_yaml, mock_log_dir):
|
||||||
|
|
||||||
run_called_args = {
|
run_called_args = {
|
||||||
@ -161,13 +171,15 @@ class TestRun(BaseCommand):
|
|||||||
'python_interpreter': sys.executable,
|
'python_interpreter': sys.executable,
|
||||||
'quiet': True,
|
'quiet': True,
|
||||||
'ssh_user': 'doe',
|
'ssh_user': 'doe',
|
||||||
'log_path': mock_log_dir}
|
'log_path': mock_log_dir,
|
||||||
|
'validation_config': {}
|
||||||
|
}
|
||||||
|
|
||||||
arglist = ['--validation', 'foo',
|
arglist = ['--validation', 'foo',
|
||||||
'--extra-vars-file', '/foo/vars.yaml']
|
'--extra-vars-file', '/foo/vars.yaml']
|
||||||
verifylist = [('validation_name', ['foo']),
|
verifylist = [('validation_name', ['foo']),
|
||||||
('extra_vars_file', '/foo/vars.yaml')]
|
('extra_vars_file', '/foo/vars.yaml')]
|
||||||
|
self._set_args(arglist)
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
self.cmd.take_action(parsed_args)
|
self.cmd.take_action(parsed_args)
|
||||||
mock_run.assert_called_with(**run_called_args)
|
mock_run.assert_called_with(**run_called_args)
|
||||||
@ -178,7 +190,9 @@ class TestRun(BaseCommand):
|
|||||||
@mock.patch('validations_libs.validation_actions.ValidationActions.'
|
@mock.patch('validations_libs.validation_actions.ValidationActions.'
|
||||||
'run_validations',
|
'run_validations',
|
||||||
return_value=copy.deepcopy(fakes.FAKE_SUCCESS_RUN))
|
return_value=copy.deepcopy(fakes.FAKE_SUCCESS_RUN))
|
||||||
def test_run_command_extra_env_vars(self, mock_run, mock_user, mock_log_dir):
|
@mock.patch('validations_libs.utils.load_config', return_value={})
|
||||||
|
def test_run_command_extra_env_vars(self, mock_config, mock_run,
|
||||||
|
mock_user, mock_log_dir):
|
||||||
run_called_args = {
|
run_called_args = {
|
||||||
'inventory': 'localhost',
|
'inventory': 'localhost',
|
||||||
'limit_hosts': None,
|
'limit_hosts': None,
|
||||||
@ -193,13 +207,15 @@ class TestRun(BaseCommand):
|
|||||||
'python_interpreter': sys.executable,
|
'python_interpreter': sys.executable,
|
||||||
'quiet': True,
|
'quiet': True,
|
||||||
'ssh_user': 'doe',
|
'ssh_user': 'doe',
|
||||||
'log_path': mock_log_dir}
|
'log_path': mock_log_dir,
|
||||||
|
'validation_config': {}
|
||||||
|
}
|
||||||
|
|
||||||
arglist = ['--validation', 'foo',
|
arglist = ['--validation', 'foo',
|
||||||
'--extra-env-vars', 'key=value']
|
'--extra-env-vars', 'key=value']
|
||||||
verifylist = [('validation_name', ['foo']),
|
verifylist = [('validation_name', ['foo']),
|
||||||
('extra_env_vars', {'key': 'value'})]
|
('extra_env_vars', {'key': 'value'})]
|
||||||
|
self._set_args(arglist)
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
self.cmd.take_action(parsed_args)
|
self.cmd.take_action(parsed_args)
|
||||||
mock_run.assert_called_with(**run_called_args)
|
mock_run.assert_called_with(**run_called_args)
|
||||||
@ -210,7 +226,9 @@ class TestRun(BaseCommand):
|
|||||||
@mock.patch('validations_libs.validation_actions.ValidationActions.'
|
@mock.patch('validations_libs.validation_actions.ValidationActions.'
|
||||||
'run_validations',
|
'run_validations',
|
||||||
return_value=copy.deepcopy(fakes.FAKE_SUCCESS_RUN))
|
return_value=copy.deepcopy(fakes.FAKE_SUCCESS_RUN))
|
||||||
|
@mock.patch('validations_libs.utils.load_config', return_value={})
|
||||||
def test_run_command_extra_env_vars_with_custom_callback(self,
|
def test_run_command_extra_env_vars_with_custom_callback(self,
|
||||||
|
mock_config,
|
||||||
mock_run,
|
mock_run,
|
||||||
mock_user,
|
mock_user,
|
||||||
mock_log_dir):
|
mock_log_dir):
|
||||||
@ -229,13 +247,15 @@ class TestRun(BaseCommand):
|
|||||||
'extra_env_vars': {'ANSIBLE_STDOUT_CALLBACK': 'default'},
|
'extra_env_vars': {'ANSIBLE_STDOUT_CALLBACK': 'default'},
|
||||||
'python_interpreter': sys.executable,
|
'python_interpreter': sys.executable,
|
||||||
'quiet': False,
|
'quiet': False,
|
||||||
'ssh_user': 'doe'}
|
'ssh_user': 'doe',
|
||||||
|
'validation_config': {}
|
||||||
|
}
|
||||||
|
|
||||||
arglist = ['--validation', 'foo',
|
arglist = ['--validation', 'foo',
|
||||||
'--extra-env-vars', 'ANSIBLE_STDOUT_CALLBACK=default']
|
'--extra-env-vars', 'ANSIBLE_STDOUT_CALLBACK=default']
|
||||||
verifylist = [('validation_name', ['foo']),
|
verifylist = [('validation_name', ['foo']),
|
||||||
('extra_env_vars', {'ANSIBLE_STDOUT_CALLBACK': 'default'})]
|
('extra_env_vars', {'ANSIBLE_STDOUT_CALLBACK': 'default'})]
|
||||||
|
self._set_args(arglist)
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
self.cmd.take_action(parsed_args)
|
self.cmd.take_action(parsed_args)
|
||||||
mock_run.assert_called_with(**run_called_args)
|
mock_run.assert_called_with(**run_called_args)
|
||||||
@ -246,7 +266,10 @@ class TestRun(BaseCommand):
|
|||||||
@mock.patch('validations_libs.validation_actions.ValidationActions.'
|
@mock.patch('validations_libs.validation_actions.ValidationActions.'
|
||||||
'run_validations',
|
'run_validations',
|
||||||
return_value=copy.deepcopy(fakes.FAKE_SUCCESS_RUN))
|
return_value=copy.deepcopy(fakes.FAKE_SUCCESS_RUN))
|
||||||
def test_run_command_extra_env_vars_twice(self, mock_run, mock_user, mock_log_dir):
|
@mock.patch('validations_libs.utils.load_config', return_value={})
|
||||||
|
def test_run_command_extra_env_vars_twice(self, mock_config,
|
||||||
|
mock_run, mock_user,
|
||||||
|
mock_log_dir):
|
||||||
run_called_args = {
|
run_called_args = {
|
||||||
'inventory': 'localhost',
|
'inventory': 'localhost',
|
||||||
'limit_hosts': None,
|
'limit_hosts': None,
|
||||||
@ -261,14 +284,16 @@ class TestRun(BaseCommand):
|
|||||||
'python_interpreter': sys.executable,
|
'python_interpreter': sys.executable,
|
||||||
'quiet': True,
|
'quiet': True,
|
||||||
'ssh_user': 'doe',
|
'ssh_user': 'doe',
|
||||||
'log_path': mock_log_dir}
|
'log_path': mock_log_dir,
|
||||||
|
'validation_config': {}
|
||||||
|
}
|
||||||
|
|
||||||
arglist = ['--validation', 'foo',
|
arglist = ['--validation', 'foo',
|
||||||
'--extra-env-vars', 'key=value1',
|
'--extra-env-vars', 'key=value1',
|
||||||
'--extra-env-vars', 'key=value2']
|
'--extra-env-vars', 'key=value2']
|
||||||
verifylist = [('validation_name', ['foo']),
|
verifylist = [('validation_name', ['foo']),
|
||||||
('extra_env_vars', {'key': 'value2'})]
|
('extra_env_vars', {'key': 'value2'})]
|
||||||
|
self._set_args(arglist)
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
self.cmd.take_action(parsed_args)
|
self.cmd.take_action(parsed_args)
|
||||||
mock_run.assert_called_with(**run_called_args)
|
mock_run.assert_called_with(**run_called_args)
|
||||||
@ -279,7 +304,9 @@ class TestRun(BaseCommand):
|
|||||||
@mock.patch('validations_libs.validation_actions.ValidationActions.'
|
@mock.patch('validations_libs.validation_actions.ValidationActions.'
|
||||||
'run_validations',
|
'run_validations',
|
||||||
return_value=copy.deepcopy(fakes.FAKE_SUCCESS_RUN))
|
return_value=copy.deepcopy(fakes.FAKE_SUCCESS_RUN))
|
||||||
|
@mock.patch('validations_libs.utils.load_config', return_value={})
|
||||||
def test_run_command_extra_env_vars_and_extra_vars(self,
|
def test_run_command_extra_env_vars_and_extra_vars(self,
|
||||||
|
mock_config,
|
||||||
mock_run,
|
mock_run,
|
||||||
mock_user,
|
mock_user,
|
||||||
mock_log_dir):
|
mock_log_dir):
|
||||||
@ -297,7 +324,9 @@ class TestRun(BaseCommand):
|
|||||||
'python_interpreter': sys.executable,
|
'python_interpreter': sys.executable,
|
||||||
'quiet': True,
|
'quiet': True,
|
||||||
'ssh_user': 'doe',
|
'ssh_user': 'doe',
|
||||||
'log_path': mock_log_dir}
|
'log_path': mock_log_dir,
|
||||||
|
'validation_config': {}
|
||||||
|
}
|
||||||
|
|
||||||
arglist = ['--validation', 'foo',
|
arglist = ['--validation', 'foo',
|
||||||
'--extra-vars', 'key=value',
|
'--extra-vars', 'key=value',
|
||||||
@ -305,7 +334,7 @@ class TestRun(BaseCommand):
|
|||||||
verifylist = [('validation_name', ['foo']),
|
verifylist = [('validation_name', ['foo']),
|
||||||
('extra_vars', {'key': 'value'}),
|
('extra_vars', {'key': 'value'}),
|
||||||
('extra_env_vars', {'key2': 'value2'})]
|
('extra_env_vars', {'key2': 'value2'})]
|
||||||
|
self._set_args(arglist)
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
self.cmd.take_action(parsed_args)
|
self.cmd.take_action(parsed_args)
|
||||||
mock_run.assert_called_with(**run_called_args)
|
mock_run.assert_called_with(**run_called_args)
|
||||||
@ -325,7 +354,9 @@ class TestRun(BaseCommand):
|
|||||||
@mock.patch('validations_libs.validation_actions.ValidationActions.'
|
@mock.patch('validations_libs.validation_actions.ValidationActions.'
|
||||||
'run_validations',
|
'run_validations',
|
||||||
return_value=copy.deepcopy(fakes.FAKE_FAILED_RUN))
|
return_value=copy.deepcopy(fakes.FAKE_FAILED_RUN))
|
||||||
def test_run_command_failed_validation(self, mock_run, mock_user, mock_log_dir):
|
@mock.patch('validations_libs.utils.load_config', return_value={})
|
||||||
|
def test_run_command_failed_validation(self, mock_config,
|
||||||
|
mock_run, mock_user, mock_log_dir):
|
||||||
run_called_args = {
|
run_called_args = {
|
||||||
'inventory': 'localhost',
|
'inventory': 'localhost',
|
||||||
'limit_hosts': None,
|
'limit_hosts': None,
|
||||||
@ -340,10 +371,14 @@ class TestRun(BaseCommand):
|
|||||||
'python_interpreter': sys.executable,
|
'python_interpreter': sys.executable,
|
||||||
'quiet': True,
|
'quiet': True,
|
||||||
'ssh_user': 'doe',
|
'ssh_user': 'doe',
|
||||||
'log_path': mock_log_dir}
|
'log_path': mock_log_dir,
|
||||||
|
'validation_config': {}
|
||||||
|
}
|
||||||
|
|
||||||
arglist = ['--validation', 'foo']
|
arglist = ['--validation', 'foo']
|
||||||
verifylist = [('validation_name', ['foo'])]
|
verifylist = [('validation_name', ['foo'])]
|
||||||
|
|
||||||
|
self._set_args(arglist)
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
self.assertRaises(RuntimeError, self.cmd.take_action, parsed_args)
|
self.assertRaises(RuntimeError, self.cmd.take_action, parsed_args)
|
||||||
mock_run.assert_called_with(**run_called_args)
|
mock_run.assert_called_with(**run_called_args)
|
||||||
@ -353,7 +388,9 @@ class TestRun(BaseCommand):
|
|||||||
@mock.patch('validations_libs.validation_actions.ValidationActions.'
|
@mock.patch('validations_libs.validation_actions.ValidationActions.'
|
||||||
'run_validations',
|
'run_validations',
|
||||||
return_value=[])
|
return_value=[])
|
||||||
def test_run_command_no_validation(self, mock_run, mock_user):
|
@mock.patch('validations_libs.utils.load_config', return_value={})
|
||||||
|
def test_run_command_no_validation(self, mock_config, mock_run,
|
||||||
|
mock_user):
|
||||||
run_called_args = {
|
run_called_args = {
|
||||||
'inventory': 'localhost',
|
'inventory': 'localhost',
|
||||||
'limit_hosts': None,
|
'limit_hosts': None,
|
||||||
@ -367,10 +404,85 @@ class TestRun(BaseCommand):
|
|||||||
'extra_env_vars': {'key2': 'value2'},
|
'extra_env_vars': {'key2': 'value2'},
|
||||||
'python_interpreter': sys.executable,
|
'python_interpreter': sys.executable,
|
||||||
'quiet': True,
|
'quiet': True,
|
||||||
'ssh_user': 'doe'}
|
'ssh_user': 'doe',
|
||||||
|
'validation_config': {}
|
||||||
|
}
|
||||||
|
|
||||||
arglist = ['--validation', 'foo']
|
arglist = ['--validation', 'foo']
|
||||||
verifylist = [('validation_name', ['foo'])]
|
verifylist = [('validation_name', ['foo'])]
|
||||||
|
|
||||||
|
self._set_args(arglist)
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
self.assertRaises(RuntimeError, self.cmd.take_action, parsed_args)
|
self.assertRaises(RuntimeError, self.cmd.take_action, parsed_args)
|
||||||
|
|
||||||
|
@mock.patch('validations_libs.constants.VALIDATIONS_LOG_BASEDIR')
|
||||||
|
@mock.patch('getpass.getuser',
|
||||||
|
return_value='doe')
|
||||||
|
@mock.patch('validations_libs.validation_actions.ValidationActions.'
|
||||||
|
'run_validations',
|
||||||
|
return_value=fakes.FAKE_SUCCESS_RUN)
|
||||||
|
def test_run_with_wrong_config(self, mock_run,
|
||||||
|
mock_user, mock_log_dir):
|
||||||
|
arglist = ['--validation', 'foo', '--config', 'wrong.cfg']
|
||||||
|
verifylist = [('validation_name', ['foo']),
|
||||||
|
('config', 'wrong.cfg')]
|
||||||
|
|
||||||
|
run_called_args = {
|
||||||
|
'inventory': 'localhost',
|
||||||
|
'limit_hosts': None,
|
||||||
|
'group': [],
|
||||||
|
'category': [],
|
||||||
|
'product': [],
|
||||||
|
'extra_vars': None,
|
||||||
|
'validations_dir': '/usr/share/ansible/validation-playbooks',
|
||||||
|
'base_dir': '/usr/share/ansible',
|
||||||
|
'validation_name': ['foo'],
|
||||||
|
'extra_env_vars': None,
|
||||||
|
'python_interpreter': sys.executable,
|
||||||
|
'quiet': True,
|
||||||
|
'ssh_user': 'doe',
|
||||||
|
'log_path': mock_log_dir,
|
||||||
|
'validation_config': {}
|
||||||
|
}
|
||||||
|
|
||||||
|
self._set_args(arglist)
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
self.cmd.take_action(parsed_args)
|
||||||
|
mock_run.assert_called_with(**run_called_args)
|
||||||
|
|
||||||
|
@mock.patch('validations_libs.constants.VALIDATIONS_LOG_BASEDIR')
|
||||||
|
@mock.patch('getpass.getuser',
|
||||||
|
return_value='doe')
|
||||||
|
@mock.patch('validations_libs.validation_actions.ValidationActions.'
|
||||||
|
'run_validations',
|
||||||
|
return_value=fakes.FAKE_SUCCESS_RUN)
|
||||||
|
@mock.patch('os.path.exists', return_value=True)
|
||||||
|
def test_run_with_config(self, mock_exists,
|
||||||
|
mock_run, mock_user,
|
||||||
|
mock_log_dir):
|
||||||
|
arglist = ['--validation', 'foo', '--config', 'config.cfg']
|
||||||
|
verifylist = [('validation_name', ['foo']),
|
||||||
|
('config', 'config.cfg')]
|
||||||
|
|
||||||
|
run_called_args = {
|
||||||
|
'inventory': 'localhost',
|
||||||
|
'limit_hosts': None,
|
||||||
|
'group': [],
|
||||||
|
'category': [],
|
||||||
|
'product': [],
|
||||||
|
'extra_vars': None,
|
||||||
|
'validations_dir': '/usr/share/ansible/validation-playbooks',
|
||||||
|
'base_dir': '/usr/share/ansible',
|
||||||
|
'validation_name': ['foo'],
|
||||||
|
'extra_env_vars': None,
|
||||||
|
'python_interpreter': sys.executable,
|
||||||
|
'quiet': True,
|
||||||
|
'ssh_user': 'doe',
|
||||||
|
'log_path': mock_log_dir,
|
||||||
|
'validation_config': {}
|
||||||
|
}
|
||||||
|
|
||||||
|
self._set_args(arglist)
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
self.cmd.take_action(parsed_args)
|
||||||
|
mock_run.assert_called_with(**run_called_args)
|
||||||
|
@ -33,6 +33,7 @@ class TestShow(BaseCommand):
|
|||||||
def test_show_validations(self, mock_show):
|
def test_show_validations(self, mock_show):
|
||||||
arglist = ['foo']
|
arglist = ['foo']
|
||||||
verifylist = [('validation_name', 'foo')]
|
verifylist = [('validation_name', 'foo')]
|
||||||
|
self._set_args(arglist)
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
self.cmd.take_action(parsed_args)
|
self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
|
@ -318,6 +318,23 @@ FAKE_FAILED_RUN = [{'Duration': '0:00:01.761',
|
|||||||
|
|
||||||
FAKE_VALIDATIONS_PATH = '/usr/share/ansible/validation-playbooks'
|
FAKE_VALIDATIONS_PATH = '/usr/share/ansible/validation-playbooks'
|
||||||
|
|
||||||
|
DEFAULT_CONFIG = {'validation_dir': '/usr/share/ansible/validation-playbooks',
|
||||||
|
'ansible_base_dir': '/usr/share/ansible/',
|
||||||
|
'output_log': 'output.log',
|
||||||
|
'history_limit': 15,
|
||||||
|
'fit_width': True}
|
||||||
|
|
||||||
|
WRONG_HISTORY_CONFIG = {'default': {'history_limit': 0}}
|
||||||
|
|
||||||
|
ANSIBLE_RUNNER_CONFIG = {'verbosity': 5,
|
||||||
|
'fact_cache_type': 'jsonfile',
|
||||||
|
'quiet': True, 'rotate_artifacts': 256}
|
||||||
|
|
||||||
|
ANSIBLE_ENVIRONNMENT_CONFIG = {'ANSIBLE_CALLBACK_WHITELIST':
|
||||||
|
'validation_stdout,validation_json,'
|
||||||
|
'profile_tasks',
|
||||||
|
'ANSIBLE_STDOUT_CALLBACK': 'validation_stdout'}
|
||||||
|
|
||||||
|
|
||||||
def fake_ansible_runner_run_return(status='successful', rc=0):
|
def fake_ansible_runner_run_return(status='successful', rc=0):
|
||||||
return status, rc
|
return status, rc
|
||||||
|
@ -348,3 +348,83 @@ class TestAnsible(TestCase):
|
|||||||
})
|
})
|
||||||
|
|
||||||
mock_config.assert_called_once_with(**opt)
|
mock_config.assert_called_once_with(**opt)
|
||||||
|
|
||||||
|
@mock.patch('os.path.exists', return_value=True)
|
||||||
|
@mock.patch('os.makedirs')
|
||||||
|
@mock.patch.object(Runner, 'run',
|
||||||
|
return_value=fakes.fake_ansible_runner_run_return(rc=0))
|
||||||
|
@mock.patch('ansible_runner.utils.dump_artifact', autospec=True,
|
||||||
|
return_value="/foo/inventory.yaml")
|
||||||
|
@mock.patch('six.moves.builtins.open')
|
||||||
|
@mock.patch('ansible_runner.runner_config.RunnerConfig')
|
||||||
|
def test_run_success_with_config(self, mock_config, mock_open,
|
||||||
|
mock_dump_artifact, mock_run,
|
||||||
|
mock_mkdirs, mock_exists
|
||||||
|
):
|
||||||
|
fake_config = {'default': fakes.DEFAULT_CONFIG,
|
||||||
|
'ansible_environment':
|
||||||
|
fakes.ANSIBLE_ENVIRONNMENT_CONFIG,
|
||||||
|
'ansible_runner': fakes.ANSIBLE_RUNNER_CONFIG
|
||||||
|
}
|
||||||
|
_playbook, _rc, _status = self.run.run(
|
||||||
|
playbook='existing.yaml',
|
||||||
|
inventory='localhost,',
|
||||||
|
workdir='/tmp',
|
||||||
|
connection='local',
|
||||||
|
ansible_artifact_path='/tmp',
|
||||||
|
validation_cfg_file=fake_config
|
||||||
|
)
|
||||||
|
self.assertEqual((_playbook, _rc, _status),
|
||||||
|
('existing.yaml', 0, 'successful'))
|
||||||
|
mock_open.assert_called_with('/tmp/validation.cfg', 'w')
|
||||||
|
|
||||||
|
@mock.patch('os.path.exists', return_value=True)
|
||||||
|
@mock.patch('os.makedirs')
|
||||||
|
@mock.patch.object(Runner, 'run',
|
||||||
|
return_value=fakes.fake_ansible_runner_run_return(rc=0))
|
||||||
|
@mock.patch('ansible_runner.utils.dump_artifact', autospec=True,
|
||||||
|
return_value="/foo/inventory.yaml")
|
||||||
|
@mock.patch('six.moves.builtins.open')
|
||||||
|
@mock.patch('ansible_runner.runner_config.RunnerConfig')
|
||||||
|
def test_run_success_with_empty_config(self, mock_config, mock_open,
|
||||||
|
mock_dump_artifact, mock_run,
|
||||||
|
mock_mkdirs, mock_exists
|
||||||
|
):
|
||||||
|
fake_config = {}
|
||||||
|
_playbook, _rc, _status = self.run.run(
|
||||||
|
playbook='existing.yaml',
|
||||||
|
inventory='localhost,',
|
||||||
|
workdir='/tmp',
|
||||||
|
connection='local',
|
||||||
|
ansible_cfg_file='/foo.cfg',
|
||||||
|
ansible_artifact_path='/tmp',
|
||||||
|
validation_cfg_file=fake_config
|
||||||
|
)
|
||||||
|
self.assertEqual((_playbook, _rc, _status),
|
||||||
|
('existing.yaml', 0, 'successful'))
|
||||||
|
mock_open.assert_not_called()
|
||||||
|
|
||||||
|
@mock.patch('os.path.exists', return_value=True)
|
||||||
|
@mock.patch('os.makedirs')
|
||||||
|
@mock.patch.object(Runner, 'run',
|
||||||
|
return_value=fakes.fake_ansible_runner_run_return(rc=0))
|
||||||
|
@mock.patch('ansible_runner.utils.dump_artifact', autospec=True,
|
||||||
|
return_value="/foo/inventory.yaml")
|
||||||
|
@mock.patch('six.moves.builtins.open')
|
||||||
|
@mock.patch('ansible_runner.runner_config.RunnerConfig')
|
||||||
|
def test_run_success_with_ansible_config(self, mock_config, mock_open,
|
||||||
|
mock_dump_artifact, mock_run,
|
||||||
|
mock_mkdirs, mock_exists
|
||||||
|
):
|
||||||
|
fake_config = {}
|
||||||
|
_playbook, _rc, _status = self.run.run(
|
||||||
|
playbook='existing.yaml',
|
||||||
|
inventory='localhost,',
|
||||||
|
workdir='/tmp',
|
||||||
|
connection='local',
|
||||||
|
ansible_artifact_path='/tmp',
|
||||||
|
validation_cfg_file=fake_config
|
||||||
|
)
|
||||||
|
self.assertEqual((_playbook, _rc, _status),
|
||||||
|
('existing.yaml', 0, 'successful'))
|
||||||
|
mock_open.assert_called_with('/tmp/ansible.cfg', 'w')
|
||||||
|
@ -389,3 +389,40 @@ class TestUtils(TestCase):
|
|||||||
"""Test if failure to create artifacts dir raises 'RuntimeError'.
|
"""Test if failure to create artifacts dir raises 'RuntimeError'.
|
||||||
"""
|
"""
|
||||||
self.assertRaises(RuntimeError, utils.create_artifacts_dir, "/foo/bar")
|
self.assertRaises(RuntimeError, utils.create_artifacts_dir, "/foo/bar")
|
||||||
|
|
||||||
|
def test_eval_types_str(self):
|
||||||
|
self.assertIsInstance(utils._eval_types('/usr'), str)
|
||||||
|
|
||||||
|
def test_eval_types_bool(self):
|
||||||
|
self.assertIsInstance(utils._eval_types('True'), bool)
|
||||||
|
|
||||||
|
def test_eval_types_int(self):
|
||||||
|
self.assertIsInstance(utils._eval_types('15'), int)
|
||||||
|
|
||||||
|
def test_eval_types_dict(self):
|
||||||
|
self.assertIsInstance(utils._eval_types('{}'), dict)
|
||||||
|
|
||||||
|
@mock.patch('os.path.exists', return_value=True)
|
||||||
|
@mock.patch('configparser.ConfigParser.sections',
|
||||||
|
return_value=['default'])
|
||||||
|
def test_load_config(self, mock_config, mock_exists):
|
||||||
|
results = utils.load_config('foo.cfg')
|
||||||
|
self.assertEqual(results, {})
|
||||||
|
|
||||||
|
def test_default_load_config(self):
|
||||||
|
results = utils.load_config('validation.cfg')
|
||||||
|
self.assertEqual(results['default'], fakes.DEFAULT_CONFIG)
|
||||||
|
|
||||||
|
def test_ansible_runner_load_config(self):
|
||||||
|
results = utils.load_config('validation.cfg')
|
||||||
|
self.assertEqual(results['ansible_runner'],
|
||||||
|
fakes.ANSIBLE_RUNNER_CONFIG)
|
||||||
|
|
||||||
|
def test_ansible_environment_config_load_config(self):
|
||||||
|
results = utils.load_config('validation.cfg')
|
||||||
|
self.assertEqual(
|
||||||
|
results['ansible_environment']['ANSIBLE_CALLBACK_WHITELIST'],
|
||||||
|
fakes.ANSIBLE_ENVIRONNMENT_CONFIG['ANSIBLE_CALLBACK_WHITELIST'])
|
||||||
|
self.assertEqual(
|
||||||
|
results['ansible_environment']['ANSIBLE_STDOUT_CALLBACK'],
|
||||||
|
fakes.ANSIBLE_ENVIRONNMENT_CONFIG['ANSIBLE_STDOUT_CALLBACK'])
|
||||||
|
@ -104,13 +104,14 @@ class TestValidationActions(TestCase):
|
|||||||
'extra_vars': None,
|
'extra_vars': None,
|
||||||
'limit_hosts': '!cloud1',
|
'limit_hosts': '!cloud1',
|
||||||
'extra_env_variables': None,
|
'extra_env_variables': None,
|
||||||
'ansible_cfg': None,
|
'ansible_cfg_file': None,
|
||||||
'gathering_policy': 'explicit',
|
'gathering_policy': 'explicit',
|
||||||
'ansible_artifact_path': '/var/log/validations/artifacts/123_fake.yaml_time',
|
'ansible_artifact_path': '/var/log/validations/artifacts/123_fake.yaml_time',
|
||||||
'log_path': '/var/log/validations',
|
'log_path': '/var/log/validations',
|
||||||
'run_async': False,
|
'run_async': False,
|
||||||
'python_interpreter': None,
|
'python_interpreter': None,
|
||||||
'ssh_user': None
|
'ssh_user': None,
|
||||||
|
'validation_cfg_file': None
|
||||||
}
|
}
|
||||||
|
|
||||||
playbook = ['fake.yaml']
|
playbook = ['fake.yaml']
|
||||||
@ -164,13 +165,14 @@ class TestValidationActions(TestCase):
|
|||||||
'extra_vars': None,
|
'extra_vars': None,
|
||||||
'limit_hosts': '!cloud1,cloud,!cloud2',
|
'limit_hosts': '!cloud1,cloud,!cloud2',
|
||||||
'extra_env_variables': None,
|
'extra_env_variables': None,
|
||||||
'ansible_cfg': None,
|
'ansible_cfg_file': None,
|
||||||
'gathering_policy': 'explicit',
|
'gathering_policy': 'explicit',
|
||||||
'ansible_artifact_path': '/var/log/validations/artifacts/123_fake.yaml_time',
|
'ansible_artifact_path': '/var/log/validations/artifacts/123_fake.yaml_time',
|
||||||
'log_path': '/var/log/validations',
|
'log_path': '/var/log/validations',
|
||||||
'run_async': False,
|
'run_async': False,
|
||||||
'python_interpreter': None,
|
'python_interpreter': None,
|
||||||
'ssh_user': None
|
'ssh_user': None,
|
||||||
|
'validation_cfg_file': None
|
||||||
}
|
}
|
||||||
|
|
||||||
playbook = ['fake.yaml']
|
playbook = ['fake.yaml']
|
||||||
|
@ -12,11 +12,15 @@
|
|||||||
# 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 ast
|
||||||
|
import configparser
|
||||||
import datetime
|
import datetime
|
||||||
import glob
|
import glob
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
import site
|
||||||
import six
|
import six
|
||||||
|
import sys
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from os.path import join
|
from os.path import join
|
||||||
@ -488,3 +492,94 @@ def get_validations_parameters(validations_data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
return params
|
return params
|
||||||
|
|
||||||
|
|
||||||
|
def _eval_types(value):
|
||||||
|
try:
|
||||||
|
return int(value)
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
return ast.literal_eval(value)
|
||||||
|
except (SyntaxError, NameError, ValueError):
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
return str(value)
|
||||||
|
except ValueError:
|
||||||
|
msg = ("Can not eval or type not supported for value: {},").format(
|
||||||
|
value)
|
||||||
|
raise ValueError(msg)
|
||||||
|
|
||||||
|
|
||||||
|
def load_config(config):
|
||||||
|
"""Load Config File from CLI"""
|
||||||
|
if not os.path.exists(config):
|
||||||
|
msg = ("Config file {} could not be found, ignoring...").format(config)
|
||||||
|
LOG.warning(msg)
|
||||||
|
return {}
|
||||||
|
else:
|
||||||
|
msg = "Validation config file found: {}".format(config)
|
||||||
|
LOG.info(msg)
|
||||||
|
parser = configparser.ConfigParser()
|
||||||
|
parser.optionxform = str
|
||||||
|
parser.read(config)
|
||||||
|
data = {}
|
||||||
|
try:
|
||||||
|
for section in parser.sections():
|
||||||
|
for keys, values in parser.items(section):
|
||||||
|
if section not in data:
|
||||||
|
# Init section in dictionary
|
||||||
|
data[section] = {}
|
||||||
|
if section == 'ansible_environment':
|
||||||
|
# for Ansible environment variables we dont want to cast
|
||||||
|
# types, each values should a type String.
|
||||||
|
data[section][keys] = values
|
||||||
|
elif section == 'ansible_runner' and \
|
||||||
|
keys not in constants.ANSIBLE_RUNNER_CONFIG_PARAMETERS:
|
||||||
|
# for Ansible runner parameters, we select only a set
|
||||||
|
# of parameters which will be passed as **kwargs in the
|
||||||
|
# runner, so we have to ignore all the others.
|
||||||
|
msg = ("Incompatible key found for ansible_runner section {}, "
|
||||||
|
"ignoring {} ...").format(section, keys)
|
||||||
|
LOG.warning(msg)
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
data[section][keys] = _eval_types(values)
|
||||||
|
except configparser.NoSectionError:
|
||||||
|
msg = ("Wrong format for the config file {}, "
|
||||||
|
"section {} can not be found, ignoring...").format(config,
|
||||||
|
section)
|
||||||
|
LOG.warning(msg)
|
||||||
|
return {}
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def find_config_file(config_file_name='validation.cfg'):
|
||||||
|
""" Find the config file for Validation in the following order:
|
||||||
|
* environment validation VALIDATION_CONFIG
|
||||||
|
* current user directory
|
||||||
|
* user home directory
|
||||||
|
* Python prefix path which has been used for the installation
|
||||||
|
* /etc/validation.cfg
|
||||||
|
"""
|
||||||
|
def _check_path(path):
|
||||||
|
if os.path.exists(path):
|
||||||
|
if os.path.isfile(path) and os.access(path,
|
||||||
|
os.R_OK):
|
||||||
|
return path
|
||||||
|
# Build a list of potential paths with the correct order:
|
||||||
|
paths = []
|
||||||
|
env_config = os.getenv("VALIDATION_CONFIG", "")
|
||||||
|
if _check_path(env_config):
|
||||||
|
return env_config
|
||||||
|
paths.append(os.getcwd())
|
||||||
|
paths.append(os.path.expanduser('~'))
|
||||||
|
for prefix in site.PREFIXES:
|
||||||
|
paths.append(os.path.join(prefix, 'etc'))
|
||||||
|
paths.append('/etc')
|
||||||
|
|
||||||
|
for path in paths:
|
||||||
|
current_path = os.path.join(path, config_file_name)
|
||||||
|
if _check_path(current_path):
|
||||||
|
return current_path
|
||||||
|
return current_path
|
||||||
|
@ -267,7 +267,8 @@ class ValidationActions(object):
|
|||||||
log_path=constants.VALIDATIONS_LOG_BASEDIR,
|
log_path=constants.VALIDATIONS_LOG_BASEDIR,
|
||||||
python_interpreter=None, skip_list=None,
|
python_interpreter=None, skip_list=None,
|
||||||
callback_whitelist=None,
|
callback_whitelist=None,
|
||||||
output_callback='validation_stdout', ssh_user=None):
|
output_callback='validation_stdout', ssh_user=None,
|
||||||
|
validation_config=None):
|
||||||
"""Run one or multiple validations by name(s), by group(s) or by
|
"""Run one or multiple validations by name(s), by group(s) or by
|
||||||
product(s)
|
product(s)
|
||||||
|
|
||||||
@ -336,6 +337,9 @@ class ValidationActions(object):
|
|||||||
:rtype: ``list``
|
:rtype: ``list``
|
||||||
:param ssh_user: Ssh user for Ansible remote connection
|
:param ssh_user: Ssh user for Ansible remote connection
|
||||||
:type ssh_user: ``string``
|
:type ssh_user: ``string``
|
||||||
|
:param validation_config: A dictionary of configuration for Validation
|
||||||
|
loaded from an validation.cfg file.
|
||||||
|
:type validation_config: ``dict``
|
||||||
|
|
||||||
:Example:
|
:Example:
|
||||||
|
|
||||||
@ -424,13 +428,14 @@ class ValidationActions(object):
|
|||||||
extra_vars=extra_vars,
|
extra_vars=extra_vars,
|
||||||
limit_hosts=_hosts,
|
limit_hosts=_hosts,
|
||||||
extra_env_variables=extra_env_vars,
|
extra_env_variables=extra_env_vars,
|
||||||
ansible_cfg=ansible_cfg,
|
ansible_cfg_file=ansible_cfg,
|
||||||
gathering_policy='explicit',
|
gathering_policy='explicit',
|
||||||
ansible_artifact_path=artifacts_dir,
|
ansible_artifact_path=artifacts_dir,
|
||||||
log_path=log_path,
|
log_path=log_path,
|
||||||
run_async=run_async,
|
run_async=run_async,
|
||||||
python_interpreter=python_interpreter,
|
python_interpreter=python_interpreter,
|
||||||
ssh_user=ssh_user)
|
ssh_user=ssh_user,
|
||||||
|
validation_cfg_file=validation_config)
|
||||||
else:
|
else:
|
||||||
_playbook, _rc, _status = run_ansible.run(
|
_playbook, _rc, _status = run_ansible.run(
|
||||||
workdir=artifacts_dir,
|
workdir=artifacts_dir,
|
||||||
@ -445,13 +450,14 @@ class ValidationActions(object):
|
|||||||
extra_vars=extra_vars,
|
extra_vars=extra_vars,
|
||||||
limit_hosts=_hosts,
|
limit_hosts=_hosts,
|
||||||
extra_env_variables=extra_env_vars,
|
extra_env_variables=extra_env_vars,
|
||||||
ansible_cfg=ansible_cfg,
|
ansible_cfg_file=ansible_cfg,
|
||||||
gathering_policy='explicit',
|
gathering_policy='explicit',
|
||||||
ansible_artifact_path=artifacts_dir,
|
ansible_artifact_path=artifacts_dir,
|
||||||
log_path=log_path,
|
log_path=log_path,
|
||||||
run_async=run_async,
|
run_async=run_async,
|
||||||
python_interpreter=python_interpreter,
|
python_interpreter=python_interpreter,
|
||||||
ssh_user=ssh_user)
|
ssh_user=ssh_user,
|
||||||
|
validation_cfg_file=validation_config)
|
||||||
results.append({'playbook': _playbook,
|
results.append({'playbook': _playbook,
|
||||||
'rc_code': _rc,
|
'rc_code': _rc,
|
||||||
'status': _status,
|
'status': _status,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user