def execute_playbooks(playbook_dir, host_file, extra_vars, host, logger=None, limit_playbooks=[]): # Import PlaybookCLI here because if it is imported before reading ansible.cfg, # ansible will try to create a tempdir that it does not have permission for. from ansible.cli.playbook import PlaybookCLI # Force requirement of a logger for 2.0 playbook runs if not logger: logger = deploy_logger inventory_dir = "%s/ansible" % settings.ANSIBLE_ROOT # Run playbooks results = [] for pb in limit_playbooks: logger.info("Executing playbook %s/%s" % (playbook_dir, pb)) args = [ "--inventory=%s" % inventory_dir, "--limit=%s" % host, "--extra-vars=%s" % json.dumps(extra_vars), "%s/%s" % (playbook_dir, pb) ] pb_runner = PlaybookCLI(args) pb_runner.parse() results.append(pb_runner.run()) if results[-1] != 0: break return results
def _extract_from_cli(self): # pylint: disable=protected-access, result = {} clis = { "module": AdHocCLI(args=["", "all"]), "playbook": PlaybookCLI(args=["", "none.yml"]) } for cli_name in clis: cli = clis[cli_name] cli.parse() cli_result = {} for option in cli.parser._get_all_options(): for name in option._long_opts: name = name[2:] if name in self._EXCLUDE_ARGS: continue shortopts = [] for opt in option._short_opts: shortopts.append(opt[1:]) cli_result[name] = { "type": option.type, "help": option.help, "shortopts": shortopts } result[cli_name] = cli_result result['module']['group'] = {"type": "string", "help": ""} result['periodic_playbook'] = result['playbook'] result['periodic_module'] = result['module'] return result
def _run_playbook(cli_args, vars_dict): """Runs ansible cli with vars dict :param vars_dict: dict, Will be passed as Ansible extra-vars :param cli_args: the list of command line arguments :return: ansible results """ # TODO(yfried): use ansible vars object instead of tmpfile # NOTE(oanufrii): !!!this import should be exactly here!!! # Ansible uses 'display' singleton from '__main__' and # gets it on module level. While we monkeypatching our # '__main__' in 'ansible_playbook' function import of # PlaybookCLI shoul be after that, to get patched # '__main__'. Otherwise ansible gets unpatched '__main__' # and creates new 'display' object with default (0) # verbosity. from ansible.cli.playbook import PlaybookCLI with tempfile.NamedTemporaryFile(prefix="ir-settings-", delete=True) as tmp: tmp.write(yaml.safe_dump(vars_dict, default_flow_style=False)) # make sure created file is readable. tmp.flush() cli_args.extend(['--extra-vars', "@" + tmp.name]) cli = PlaybookCLI(cli_args) LOG.debug('Starting ansible cli with args: {}'.format(cli_args[1:])) cli.parse() return cli.run()
def run(self): """Runs ansible CLI. Runs ansible CLI using PlaybookCLI and command line arguments stored in the self.cli_args list. Raises: CommandError: If there was error while running the command. Returns: int or list: return from the ansible PlaybookExecutor run() """ # Set the ansible.cfg that will be used by octario octario_ansible_config = self._get_ansible_config_file() if octario_ansible_config: os.environ['ANSIBLE_CONFIG'] = octario_ansible_config # Import must happen after setting ANSIBLE_CONFIG, otherwise # environment variable will not be used. from ansible.cli.playbook import PlaybookCLI ansible_cli = PlaybookCLI(self.cli_args) ansible_cli.parse() results = ansible_cli.run() if results: raise exceptions.CommandError("Failed to run tester: %s" % self.tester.get_playbook_path()) return results
def executor(tmpdir_factory, request): playbooks = request.node.callspec.params.get('playbook') playbook_files = [] for name, playbook in playbooks.items(): filename = str(tmpdir_factory.mktemp('data').join(name)) with open(filename, 'w') as f: f.write(playbook) playbook_files.append(filename) cli = PlaybookCLI(['', 'playbook.yml']) cli.parse() options = cli.parser.parse_args(['-v'])[0] loader = DataLoader() variable_manager = VariableManager() inventory = Inventory(loader=loader, variable_manager=variable_manager, host_list=['localhost']) variable_manager.set_inventory(inventory) return PlaybookExecutor(playbooks=playbook_files, inventory=inventory, variable_manager=variable_manager, loader=loader, options=options, passwords={})
def _run_playbook(playbook, service, node): # Unfortunately, there's no good way to get the options instance # with proper defaults since it's generated by argparse inside # PlaybookCLI. Due to the fact that the options can't be empty # and must contain proper values we have not choice but extract # them from PlaybookCLI instance. playbook_cli = PlaybookCLI(['to-be-stripped', playbook]) playbook_cli.parse() options = playbook_cli.options # Get others required options. loader = DataLoader() variable_manager = VariableManager() inventory = Inventory(loader, variable_manager) variable_manager.set_inventory(inventory) variable_manager.extra_vars = _get_user_settings(loader) # OpenStack Ansible deploys control plane services in LXC containers, # and use those as native hosts in its inventory. However, from # Kostyor's POV we are interested in baremetal node-by-node upgrade, # so we need to limit playbook execution only to baremetal node under # upgrade and its service's containers. inventory.subset([ host.get_vars()['inventory_hostname'] for host in _get_component_hosts_on_node(inventory, service, node) ]) # Finally, we can create a playbook executor and run the playbook. executor = PlaybookExecutor(playbooks=[playbook], inventory=inventory, variable_manager=variable_manager, loader=loader, options=options, passwords={}) executor.run()
def read_playbook(*args): args_list = list(args) cli = PlaybookCLI(args_list) parser = cli.base_parser( connect_opts=True, meta_opts=True, runas_opts=True, subset_opts=True, check_opts=True, inventory_opts=True, runtask_opts=True, vault_opts=True, fork_opts=True, module_opts=True, ) cli.options, cli.args = parser.parse_args(args_list) cli.normalize_become_options() cli.options.connection = 'smart' cli.options.inventory = 'inventory' loader, inventory, variable_manager = cli._play_prereqs(cli.options) pb = Playbook.load(cli.args[0], variable_manager, loader) for play in pb.get_plays(): yield variable_manager.get_vars(play)
def cell(create, destroy, playbook, inventory, key_file, aws_config, with_freeipa): """Manage treadmill cell on AWS""" playbook_args = [ 'ansible-playbook', '-i', inventory, '-e', 'aws_config={}'.format(aws_config) + ' freeipa={}'.format(with_freeipa), ] if create: playbook_args.extend([ playbook or deploy_path_join('cell.yml'), '--key-file', key_file, ]) elif destroy: playbook_args.append(playbook or deploy_path_join('destroy-cell.yml')) else: return playbook_cli = PlaybookCLI(playbook_args) playbook_cli.parse() playbook_cli.run()
def runPlaybook(state, pbook): try: playbookCLI = PlaybookCLI( ["ansible-playbook", "-l", state.limit, pbook]) playbookCLI.parse() playbookCLI.run() except AnsibleError as e: click.echo(e)
def test_flush_cache(self): cli = PlaybookCLI(args=["--flush-cache", "foobar.yml"]) variable_manager = VariableManager() fake_loader = DictDataLoader({'foobar.yml': ""}) inventory = InventoryManager(loader=fake_loader, sources='testhost,') cli._flush_cache(inventory, variable_manager) self.assertFalse('testhost' in variable_manager._fact_cache)
def clis(self): ''' Ansible cli objects :return: dict with cli objects ''' return { "module": AdHocCLI(args=["", "all"]), "playbook": PlaybookCLI(args=["", "none.yml"]) }
def read_playbook(playbook): cli_args = [os.path.realpath(playbook), testinfra_hosts] cli = PlaybookCLI(cli_args) cli.parse() loader, inventory, variable_manager = cli._play_prereqs() pb = Playbook.load(cli.args[0], variable_manager, loader) for play in pb.get_plays(): yield variable_manager.get_vars(play)
def run_playbook(module, extra_vars=None, extra_args=None): # Assemble parameters for playbook call path = 'test/test_playbooks/{}.yml'.format(module) playbook_opts = ['ansible-playbook', path] if extra_vars: playbook_opts.extend(['--extra-vars', extra_vars]) if extra_args: playbook_opts.extend(extra_args) cli = PlaybookCLI(playbook_opts) cli.parse() return cli.run()
def dispatch(book_id, entry, payload): print('xxxx', book_id, entry, payload) book = Book.find_by_id(book_id) if not book: return False username = payload.get('username') run_id = payload.get('req_id') or str(uuid.uuid4()) params = [book_id, run_id] options = payload.get('options') if not entry: return False if type(options) == str: args = options.split(' ') pb = PlaybookCLI(args) pb.init_parser() options, args = pb.parser.parse_args(args[1:]) options, args = pb.post_process_args(options, args) options = options.__dict__ options['entry'] = args for i in options['inventory']: if not os.path.isfile(i): i = os.path.basename(i) options['inventory'] = i break queue_name = 'book_runtime' func = run task = Task(tiger, func=func, args=params, kwargs=options, queue=queue_name, unique=True, lock=True, lock_key=book_id) run_record = { 'book_id': book_id, 'run_id': run_id, 'run_by': username, 'options': options, 'result': '', 'state': 'pending', 'created_at': 1, 'updated_at': 2, } result = Perform.insert_one(run_record) task.delay() return result.inserted_id
def test_flush_cache(self): cli = PlaybookCLI( args=["ansible-playbook", "--flush-cache", "foobar.yml"]) cli.parse() self.assertTrue(context.CLIARGS['flush_cache']) variable_manager = VariableManager() fake_loader = DictDataLoader({'foobar.yml': ""}) inventory = InventoryManager(loader=fake_loader, sources='testhost,') variable_manager.set_host_facts('testhost', {'canary': True}) self.assertTrue('testhost' in variable_manager._fact_cache) cli._flush_cache(inventory, variable_manager) self.assertFalse('testhost' in variable_manager._fact_cache)
def node(create, playbook, inventory, key_file, aws_config): """Manage treadmill node""" if create: playbook_cli = PlaybookCLI([ 'ansible-playbook', '-i', inventory, playbook, '--key-file', key_file, '-e', 'aws_config={}'.format(aws_config), ]) playbook_cli.parse() playbook_cli.run()
def deploy(self): os.chdir(self.wd) # need to chdir before importing! from ansible.cli.playbook import PlaybookCLI cli = PlaybookCLI( [ sys.argv[0], '-i', 'inventory', '-f', '10', self.playbook ] ) cli.parse() exit = cli.run() os.chdir(self.pwd) return exit
def apply_config(json_data): config_file = save_config_fille(json_data) app.logger.info('user config file: %s', config_file) args = [ ' ', '-i', '/inventory', '05_aci_deploy_app.yml', '-e', '@{}'.format(config_file) ] playbook = PlaybookCLI(args) exit_code = playbook.run() os.unlink(config_file) return exit_code == 0
def _run_playbook(cli_args, settings): """ Runs ansible cli. :param cli_args: the list of command line arguments :param settings: the settings dictionary :return: ansible results """ with tempfile.NamedTemporaryFile(prefix="ir-settings-", delete=True) as tmp: tmp.write(yaml.safe_dump(settings, default_flow_style=False)) # make sure ansible can read that file. tmp.flush() cli_args.extend(['--extra-vars', "@" + tmp.name]) cli = PlaybookCLI(cli_args) LOG.debug('Starting ansible cli with args: {}'.format(cli_args[1:])) cli.parse() return cli.run()
def _run_playbook_impl(playbook, hosts_fn=None, cwd=None, ignore_errors=False): # Unfortunately, there's no good way to get the options instance # with proper defaults since it's generated by argparse inside # PlaybookCLI. Due to the fact that the options can't be empty # and must contain proper values we have not choice but extract # them from PlaybookCLI instance. playbook_cli = PlaybookCLI(['to-be-stripped', playbook]) playbook_cli.parse() options = playbook_cli.options # Get others required options. loader = DataLoader() variable_manager = VariableManager() inventory = Inventory(loader, variable_manager) variable_manager.set_inventory(inventory) variable_manager.extra_vars = _get_user_settings(loader) # Limit playbook execution to hosts returned by 'hosts_fn'. if hosts_fn is not None: inventory.subset([ host.get_vars()['inventory_hostname'] for host in hosts_fn(inventory) ]) # Finally, we can create a playbook executor and run the playbook. executor = PlaybookExecutor(playbooks=[playbook], inventory=inventory, variable_manager=variable_manager, loader=loader, options=options, passwords={}) # Some playbooks may rely on current working directory, so better allow # to change it before execution. with _setcwd(cwd): exitcode = executor.run() # Celery treats exceptions from task as way to mark it failed. So let's # throw one to do so in case return code is not zero. if all([not ignore_errors, exitcode is not None, exitcode != 0]): raise Exception('Playbook "%s" has been finished with errors. ' 'Exit code is "%d".' % (playbook, exitcode)) return exitcode
def main(cliargs=None): data_path = resource_filename(__name__, 'data') packaging_playbooks_path = os.path.join(data_path, 'playbooks') cfg_path = os.path.join(data_path, 'ansible.cfg') if os.path.exists(cfg_path): os.environ["ANSIBLE_CONFIG"] = cfg_path # this needs to be global, as otherwise PlaybookCLI fails # to set the verbosity correctly from ansible.utils.display import Display global display display = Display() inventory_path = os.path.join(os.getcwd(), 'package_manifest.yaml') package_choices = find_packages(inventory_path) playbooks = find_playbooks(packaging_playbooks_path) parser = obal_argument_parser(playbooks.keys(), package_choices) args = parser.parse_args(cliargs) playbook_path = playbooks[args.action] if not os.path.exists(inventory_path): print("Could not find your package_manifest.yaml") exit(1) if not os.path.exists(playbook_path): print("Could not find the packaging playbooks") exit(1) from ansible.cli.playbook import PlaybookCLI ansible_args = generate_ansible_args(inventory_path, playbook_path, args) ansible_playbook = (["ansible-playbook"] + ansible_args) if args.verbose: print(ansible_playbook) cli = PlaybookCLI(ansible_playbook) cli.parse() exit_code = cli.run() sys.exit(exit_code)
def runPlaybooks(playbooks, _inventory, params=None, args=None, vault_secrets=None): inventoryArgs = ["-i", _inventory] if _inventory else [] args = ["ansible-playbook"] + inventoryArgs + (args or []) + playbooks logger.info("running " + " ".join(args)) cli = PlaybookCLI(args) context._init_global_context = _init_global_context cli.parse() # replace C.DEFAULT_STDOUT_CALLBACK with our own so we have control over logging # config/base.yml sets C.DEFAULT_STDOUT_CALLBACK == 'default' (ansible/plugins/callback/default.py) # (cli/console.py and cli/adhoc.py sets it to 'minimal' but PlaybookCLI.run() in cli/playbook.py uses the default) # see also https://github.com/projectatomic/atomic-host-tests/blob/master/callback_plugins/default.py resultsCB = ResultCallback() resultsCB.set_options() C.DEFAULT_STDOUT_CALLBACK = resultsCB _play_prereqs = cli._play_prereqs def hook_play_prereqs(): loader, inventory, variable_manager = _play_prereqs() if vault_secrets: loader.set_vault_secrets(vault_secrets) if params: variable_manager._extra_vars.update(params) resultsCB.inventoryManager = inventory resultsCB.variableManager = variable_manager return loader, inventory, variable_manager cli._play_prereqs = hook_play_prereqs oldVerbosity = display.verbosity if logging.getLogger("unfurl.ansible").getEffectiveLevel() <= 10: # debug display.verbosity = 2 try: resultsCB.exit_code = cli.run() finally: display.verbosity = oldVerbosity return resultsCB
def _run_playbook(cli_args, vars_dict): """Runs ansible cli with vars dict :param vars_dict: dict, Will be passed as Ansible extra-vars :param cli_args: the list of command line arguments :return: ansible results """ # TODO(yfried): use ansible vars object instead of tmpfile with tempfile.NamedTemporaryFile( prefix="ir-settings-", delete=True) as tmp: tmp.write(yaml.safe_dump(vars_dict, default_flow_style=False)) # make sure created file is readable. tmp.flush() cli_args.extend(['--extra-vars', "@" + tmp.name]) cli = PlaybookCLI(cli_args) LOG.debug('Starting ansible cli with args: {}'.format(cli_args[1:])) cli.parse() return cli.run()
def main(cliargs=None, application_config=ApplicationConfig): # pylint: disable=R0914 """ Main command """ cfg_path = application_config.ansible_config_path() if os.path.exists(cfg_path): os.environ["ANSIBLE_CONFIG"] = cfg_path # this needs to be global, as otherwise PlaybookCLI fails # to set the verbosity correctly from ansible.utils.display import Display # pylint: disable=all global display # pylint: disable=C0103,W0603 display = Display() inventory_path = application_config.inventory_path() targets = find_targets(inventory_path) parser = obsah_argument_parser(application_config, targets=targets) args = parser.parse_args(cliargs) if args.playbook.takes_target_parameter and not os.path.exists( inventory_path): print("Could not find your inventory at {}".format(inventory_path)) sys.exit(1) from ansible.cli.playbook import PlaybookCLI # pylint: disable=all ansible_args = generate_ansible_args(inventory_path, args, parser.obsah_arguments) ansible_playbook = (["ansible-playbook"] + ansible_args) if args.verbose: print("ANSIBLE_CONFIG={}".format(os.environ["ANSIBLE_CONFIG"]), ' '.join(ansible_playbook)) cli = PlaybookCLI(ansible_playbook) cli.parse() exit_code = cli.run() sys.exit(exit_code)
def main(cliargs=None): # pylint: disable=R0914 """ Main command """ cfg_path = get_ansible_config_path() if os.path.exists(cfg_path): os.environ["ANSIBLE_CONFIG"] = cfg_path # this needs to be global, as otherwise PlaybookCLI fails # to set the verbosity correctly from ansible.utils.display import Display global display # pylint: disable=C0103,W0603 display = Display() inventory_path = os.path.join(os.getcwd(), 'package_manifest.yaml') package_choices = find_packages(inventory_path) playbooks = find_playbooks(get_playbooks_path()) parser = obal_argument_parser(playbooks, package_choices) args = parser.parse_args(cliargs) if args.playbook.takes_package_parameter and not os.path.exists(inventory_path): print("Could not find your package_manifest.yaml") exit(1) from ansible.cli.playbook import PlaybookCLI ansible_args = generate_ansible_args(inventory_path, args) ansible_playbook = (["ansible-playbook"] + ansible_args) if args.verbose: print(ansible_playbook) cli = PlaybookCLI(ansible_playbook) cli.parse() exit_code = cli.run() sys.exit(exit_code)
def run_playbook(task, inventory='hosts_dev', play_book='fetch_config.yml'): try: cli = PlaybookCLI([" ", '-i', INVENTORY_PATH + inventory, play_book]) super(PlaybookCLI, cli).run() loader, inventory, variable_manager = cli._play_prereqs() CLI.get_host_list(inventory, context.CLIARGS['subset']) pbex = PlaybookExecutor(playbooks=context.CLIARGS['args'], inventory=inventory, variable_manager=variable_manager, loader=loader, passwords=None) pbex._tqm._stdout_callback = ResultCallback(task) pbex.run() return True except Exception as e: logger.error(e) return False
def generate_playbook_options(self, playbook): """ Use the Ansible CLI code to generate a set of options for the Playbook API. We do not know or care about the fields that may or may not be needed from the options, so we let the Ansible code parse them out and set other defaults as necessary. :return: namedtuple-esque playbook options object """ playbook_args = [ 'ansible-playbook', '-{}'.format('v' * self.verbosity), playbook ] if self.check: playbook_args.append('--check') playbook_cli = PlaybookCLI(args=playbook_args) playbook_cli.parse() playbook_cli.options.module_path = self.custom_module_path return playbook_cli.options
def main(): inventory_path = os.path.join(os.getcwd(), 'package_manifest.yaml') package_choices = find_packages(inventory_path) parser = argparse.ArgumentParser() parser.add_argument('-e', '--extra-vars', dest="extra_vars", action="append", default=[], help="""set additional variables as key=value or YAML/JSON, if filename prepend with @""") parser.add_argument("-v", "--verbose", action="count", dest="verbose", help="verbose output") parser.add_argument("--start-at-task", action="store", dest="start_at_task", help="Start at a specific task") parser.add_argument("--step", action="store_true", dest="step", default=False, help="interactive: confirm each task before running") parser.add_argument("--list-tasks", action="store_true", dest="list_tasks", default=False, help="list tasks that will be run in the playbook") parser.add_argument("action", choices=_PLAYBOOKS.keys(), help="""which action to execute""") parser.add_argument('package', metavar='package', choices=package_choices, help="the package to build") if argcomplete: argcomplete.autocomplete(parser) args = parser.parse_args() packaging_playbooks_path = resource_filename(__name__, 'data') playbook = _PLAYBOOKS[args.action] playbook_path = os.path.join(packaging_playbooks_path, playbook) cfg_path = os.path.join(packaging_playbooks_path, 'ansible.cfg') if os.path.exists(cfg_path): os.environ["ANSIBLE_CONFIG"] = cfg_path if not os.path.exists(inventory_path): print("Could not find your package_manifest.yaml") exit(1) if not os.path.exists(playbook_path): print("Could not find the packaging playbooks") exit(1) from ansible.cli.playbook import PlaybookCLI ansible_args = [ playbook_path, '--inventory', inventory_path, '--limit', args.package ] for extra_var in args.extra_vars: ansible_args.extend(["-e", extra_var]) if args.verbose: ansible_args.append("-%s" % str("v" * args.verbose)) if args.start_at_task: ansible_args.append("--start-at-task") ansible_args.append(args.start_at_task) if args.step: ansible_args.append("--step") if args.list_tasks: ansible_args = ["--list-tasks"] ansible_playbook = (["ansible-playbook"] + ansible_args) if args.verbose: print(ansible_playbook) cli = PlaybookCLI(ansible_playbook) cli.parse() cli.run()
def run_playbook(path, extra_vars=""): cli = PlaybookCLI(['ansible-playbook', path, "--extra-vars", extra_vars]) cli.parse() return cli.run()
def _run_playbook(cli_args, vars_dict, ir_workspace, ir_plugin): """Runs ansible cli with vars dict :param vars_dict: dict, Will be passed as Ansible extra-vars :param cli_args: the list of command line arguments :param ir_workspace: An Infrared Workspace object represents the active workspace :param ir_plugin: An InfraredPlugin object of the current plugin :return: ansible results """ # TODO(yfried): use ansible vars object instead of tmpfile # NOTE(oanufrii): !!!this import should be exactly here!!! # Ansible uses 'display' singleton from '__main__' and # gets it on module level. While we monkeypatching our # '__main__' in 'ansible_playbook' function import of # PlaybookCLI shoul be after that, to get patched # '__main__'. Otherwise ansible gets unpatched '__main__' # and creates new 'display' object with default (0) # verbosity. from ansible.cli.playbook import PlaybookCLI from ansible.errors import AnsibleOptionsError from ansible.errors import AnsibleParserError with tempfile.NamedTemporaryFile(mode='w+', prefix="ir-settings-", delete=True) as tmp: tmp.write(yaml.safe_dump(vars_dict, default_flow_style=False)) # make sure created file is readable. tmp.flush() cli_args.extend(['--extra-vars', "@" + tmp.name]) cli = PlaybookCLI(cli_args) LOG.debug('Starting ansible cli with args: {}'.format(cli_args[1:])) try: cli.parse() stdout = not bool( strtobool(os.environ.get('IR_ANSIBLE_NO_STDOUT', 'no'))) stderr = not bool( strtobool(os.environ.get('IR_ANSIBLE_NO_STDERR', 'no'))) ansible_outputs_dir = \ os.path.join(ir_workspace.path, 'ansible_outputs') ansible_vars_dir = \ os.path.join(ir_workspace.path, 'ansible_vars') timestamp = datetime.utcnow().strftime("%Y-%m-%d_%H-%M-%S.%f") filename_template = \ "ir_{timestamp}_{plugin_name}{postfix}.{file_ext}" for _dir in (ansible_outputs_dir, ansible_vars_dir): try: os.makedirs(_dir) except OSError as e: if e.errno != errno.EEXIST: raise if bool(strtobool(os.environ.get('IR_GEN_VARS_JSON', 'no'))): filename = filename_template.format(timestamp=timestamp, plugin_name=ir_plugin.name, postfix='', file_ext='json') vars_file = os.path.join(ansible_vars_dir, filename) with open(vars_file, 'w') as fp: json.dump(vars_dict, fp, indent=4, sort_keys=True) with IRSTDFDManager(stdout=stdout, stderr=stderr) as fd_manager: if bool( strtobool(os.environ.get('IR_ANSIBLE_LOG_OUTPUT', 'no'))): filename = filename_template.format( timestamp=timestamp, plugin_name=ir_plugin.name, postfix='', file_ext='log') log_file = os.path.join(ansible_outputs_dir, filename) fd_manager.add(open(log_file, 'w')) if bool( strtobool( os.environ.get('IR_ANSIBLE_LOG_OUTPUT_NO_ANSI', 'no'))): filename = filename_template.format( timestamp=timestamp, plugin_name=ir_plugin.name, postfix='_no_ansi', file_ext='log') log_file = os.path.join(ansible_outputs_dir, filename) fd_manager.add(NoAnsiFile(open(log_file, 'w'))) # Return the result: # 0: Success # 1: "Error" # 2: Host failed # 3: Unreachable # 4: Parser Error # 5: Options error return cli.run() except (AnsibleParserError, AnsibleOptionsError) as error: LOG.error('{}: {}'.format(type(error), error)) raise error