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(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_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 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 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 _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 main(): """Run playbook""" for flag in ('--check',): if flag not in sys.argv: sys.argv.append(flag) obj = PlaybookCLI(sys.argv) obj.parse() obj.run()
def run_pbook(self): """Run playbook in check mode with console-stdout suppressed""" for flag in ('--check',): if flag not in self.ansible_pbook_args: self.ansible_pbook_args.append(flag) obj = PlaybookCLI(self.ansible_pbook_args) obj.parse() obj.run()
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 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 __run_playbook(inventory_path, playbook_path, key_path, tags, ansibleopts): vault_password_file = vault.VAULT_PASSWORD_FILENAME if os.path.exists(vault.VAULT_PLAIN_PASSWORD_FILENAME): vault_password_file = vault.VAULT_PLAIN_PASSWORD_FILENAME cmd = ['ansible-playbook', '-i', inventory_path, '--private-key', key_path, '--vault-password-file={}'.format(vault_password_file), playbook_path] if len(tags) > 0: cmd += ['--tags', ','.join(tags)] if ansibleopts is not None: cmd += ansibleopts.strip().split() cli = PlaybookCLI(cmd) cli.parse() return cli.run()
def test_flush_cache(self): cli = PlaybookCLI(args=["ansible-playbook", "--flush-cache", "foobar.yml"]) cli.parse() self.assertTrue(cli.options.flush_cache) variable_manager = VariableManager() fake_loader = DictDataLoader({'foobar.yml': ""}) inventory = InventoryManager(loader=fake_loader, sources='testhost,') variable_manager.set_host_facts(inventory.get_host('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 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 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 _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, 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(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 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 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 _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 clis(self): ''' Ansible cli objects :return: dict with cli objects ''' return { "module": AdHocCLI(args=["", "all"]), "playbook": PlaybookCLI(args=["", "none.yml"]) }
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 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 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 runPlaybook(state, pbook): try: playbookCLI = PlaybookCLI( ["ansible-playbook", "-l", state.limit, pbook]) playbookCLI.parse() playbookCLI.run() except AnsibleError as e: click.echo(e)
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 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 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
class General(object): def __init__(self): self.cli = PlaybookCLI(sys.argv, callback=CallbackModule) self.cli.parse() def run(self): sshpass = None becomepass = None passwords = {} if not self.cli.options.listhosts and not self.cli.options.listtasks and not self.cli.options.listtags and not self.cli.options.syntax: self.cli.normalize_become_options() (sshpass, becomepass) = self.cli.ask_passwords() passwords = {'conn_pass': sshpass, 'become_pass': becomepass} loader, inventory, variable_manager = self.cli._play_prereqs( self.cli.options) for playbook_path in self.cli.args: pb = Playbook.load(playbook_path, variable_manager=variable_manager, loader=loader) plays = pb.get_plays() for play in plays: tqm = None try: tqm = TaskQueueManager( inventory=inventory, variable_manager=variable_manager, loader=loader, options=self.cli.options, passwords=passwords, stdout_callback=CallbackModule(), ) tqm.run(play) finally: if tqm is not None: tqm.cleanup()
if not options.no_ansible_galaxy: print("[+] launching ansible-galaxy") default_opts = ["ansible-galaxy"] default_opts += ["install"] default_opts += ["-r", "ansible-requirements.yml"] default_opts += ["--force"] galaxy_cli = GalaxyCLI(default_opts) galaxy_cli.parse() exit_code = galaxy_cli.run() if exit_code: clean_and_exit(tmpdir, exit_code) if not options.no_ansible: print("[+] launching ansible-playbook") default_opts = ["ansible-playbook"] default_opts += ["-i", "default_groups"] default_opts += ["-i", inventory_file] default_opts += ["-e", "@{}".format(vars_file)] if '-u' not in options.ansible_args: default_opts += ["-u", "vagrant"] if options.offline: default_opts += [ "--module-path", "ansible_plugins/modules:offline/ansible_modules/offline"] ansible_args = default_opts + options.ansible_args play_cli = PlaybookCLI(ansible_args) play_cli.parse() exit_code = play_cli.run() clean_and_exit(tmpdir, exit_code)
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