Пример #1
0
    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
Пример #2
0
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()
Пример #3
0
    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()
Пример #4
0
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={})
Пример #5
0
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()
Пример #6
0
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()
Пример #7
0
    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
Пример #8
0
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
Пример #9
0
def runPlaybook(state, pbook):
    try:
        playbookCLI = PlaybookCLI(
            ["ansible-playbook", "-l", state.limit, pbook])
        playbookCLI.parse()
        playbookCLI.run()
    except AnsibleError as e:
        click.echo(e)
Пример #10
0
 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()
Пример #11
0
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()
Пример #12
0
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)
Пример #13
0
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()
Пример #14
0
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()
Пример #15
0
    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 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)
Пример #17
0
 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()
Пример #18
0
 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
Пример #19
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()
Пример #20
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()
Пример #21
0
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
Пример #22
0
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)
Пример #23
0
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
Пример #24
0
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()
Пример #25
0
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)
Пример #26
0
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)
Пример #27
0
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()
Пример #28
0
    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
Пример #29
0
        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)
Пример #30
0
    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)
            self.package_info[h]["failed"] = True
        super(CallbackModule, self).v2_runner_item_on_failed(result)


# Initialise our custom callback
results_callback = CallbackModule()

# Read all the arguments from the cli
args = [to_text(a, errors='surrogate_or_strict') for a in sys.argv]

# Ensure dry-run option is specified
if '--check' not in args:
    args.append('--check')

pb_cli = PlaybookCLI(args)
pb_cli.parse()

#####################################################################
### Execute a playbook
# This section is copied directly from: https://github.com/ansible/ansible/blob/stable-2.9/lib/ansible/cli/playbook.py#L71

# manages passwords
sshpass = None
becomepass = None
passwords = {}

b_playbook_dirs = []
for playbook in context.CLIARGS['args']:
    if not os.path.exists(playbook):
        raise AnsibleError("the playbook: %s could not be found" % playbook)
    if not (os.path.isfile(playbook)
Пример #32
0
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()
Пример #33
0
def run_playbook(args):
    pb_cli = PlaybookCLI(args)
    pb_cli.parse()
    return pb_cli.run()
Пример #34
0
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
def run_playbook(path, extra_vars=""):
    cli = PlaybookCLI(['ansible-playbook', path, "--extra-vars", extra_vars])
    cli.parse()
    return cli.run()
Пример #36
0
    def default(self):
        verbose = self.app.pargs.verbose

        init(autoreset=True)

        if len(self.app.pargs.extra_arguments) == 0:
            self.app.args.print_help()
            print(Fore.RED + 'Error! You must specify a playbook file to run')
            sys.exit(1)

        if str(self.app.pargs.become_method).upper() not in [
                'SUDO', 'SU', 'PBRUN', 'PFEXEC', 'DOAS', 'DZDO', 'KSU', 'RUNAS'
        ]:
            print(
                Fore.RED +
                'Error! Become method must be one of sudo, su, pbrun, pfexec, doas, dzdo, ksu or runas.'
            )
            sys.exit(1)

        #if len(self.app.pargs.extra_arguments) > 0:

        playbook_path = self.app.pargs.extra_arguments[0] if len(
            self.app.pargs.extra_arguments) > 0 else "site.yml"

        if not os.path.isfile(playbook_path):
            print(Fore.RED + 'Error! The playbook file does not exist')
            sys.exit(1)

        inventory_path = self.app.pargs.inventory

        if not os.path.isfile(inventory_path):
            print(Fore.RED + 'Error! The inventory file does not exist.')
            sys.exit(1)

        # Most of the code from here down is straight copy & paste from ansible source code,
        # with a few tweaks/hacks to clean up variables that we don't want to emit in the generated
        # YAML.
        loader = DataLoader()

        pb_cli = PlaybookCLI(sys.argv[1:])
        pb_cli.parse()

        # !!!!! WARNING: THESE WILL BE INCLUDED IN THE GENERATED YAML FILE !!!!!
        (ssh_pass, become_pass) = pb_cli.ask_passwords()
        passwords = {'conn_pass': ssh_pass, 'become_pass': become_pass}

        vault_pass = None

        if self.app.pargs.ask_vault_pass:
            vault_pass = pb_cli.ask_vault_passwords()
        else:
            vault_pass = pb_cli.read_vault_password_file(
                self.app.pargs.vault_password_file, loader)

        if vault_pass is not None:
            loader.set_vault_password(vault_pass)

        # create the inventory, and filter it based on the subset specified (if any)
        host_list = self.app.pargs.inventory if self.app.pargs.inventory else constants.DEFAULT_HOST_LIST

        # FIXME: This should parse any arguments provided via -e or --extra-vars. Currently it seems
        # to parse the argument value wrongly and returns
        # '_raw_params': '<last character in variable>'. This prevents the ability to use
        # --extra-vars when executing plays.
        variable_manager = VariableManager()

        options = Options(
            verbosity=self.app.pargs.verbose,
            inventory=self.app.pargs.inventory,
            subset=self.app.pargs.limit,
            extra_vars=[self.app.pargs.extra_vars],
            forks=self.app.pargs.forks,
            ask_vault_pass=self.app.pargs.ask_vault_pass,
            vault_password_files=self.app.pargs.vault_password_file,
            tags=self.app.pargs.tags,
            skip_tags=self.app.pargs.skip_tags,
            become=self.app.pargs.become,
            become_method=self.app.pargs.become_method,
            become_user=self.app.pargs.become_user,
            become_ask_pass=self.app.pargs.ask_become_pass,
            ask_pass=self.app.pargs.ask_pass,
            private_key_file=self.app.pargs.private_key,
            remote_user=self.app.pargs.user,
            connection=self.app.pargs.connection,
            timeout=self.app.pargs.timeout,
            ssh_common_args=self.app.pargs.ssh_common_args,
            sftp_extra_args=self.app.pargs.sftp_extra_args,
            ssh_extra_args=self.app.pargs.ssh_extra_args,
            scp_extra_args=self.app.pargs.scp_extra_args,
            flush_cache=self.app.pargs.flush_cache,
            module_path=self.app.pargs.module_path)

        inventory = Inventory(loader=loader,
                              variable_manager=variable_manager,
                              host_list=host_list)

        variable_manager.extra_vars = load_extra_vars(loader=loader,
                                                      options=options)
        #variable_manager.options_vars = load_options_vars(options)

        if self.app.pargs.flush_cache:
            inventory.refresh_inventory()

        no_hosts = False

        if len(inventory.list_hosts()) == 0:
            print(
                Fore.YELLOW +
                "Warning! Provided hosts list is empty, only localhost is available."
            )
            no_hosts = True

        # FIXME: Limit is currently ignored.
        inventory.subset(self.app.pargs.limit)

        if len(inventory.list_hosts()) == 0 and no_hosts is False:
            # Invalid limit
            print(Fore.RED +
                  "Error! Specified --limit does not match any hosts.")
            sys.exit(1)

        play_data = loader.load_from_file(playbook_path)

        host_list = inventory.get_hosts(
            pattern=self.app.pargs.limit
        ) if self.app.pargs.limit else inventory.get_hosts()

        playbook = Playbook(loader=loader).load(
            playbook_path, variable_manager=variable_manager, loader=loader)

        pbex = PlaybookExecutor(playbooks=playbook.get_plays(),
                                inventory=inventory,
                                variable_manager=variable_manager,
                                loader=loader,
                                options=options,
                                passwords=passwords)

        # Ansible variables matching these strings will be excluded from the generated yaml content.
        ignored_elements = [
            'ansible_playbook_python', 'ansible_version', 'group_names',
            'inventory_hostname', 'inventory_hostname_short', 'omit',
            'playbook_dir', 'role_names'
        ]

        json_data = {}

        for host in host_list:
            host_vars = host.get_vars()
            host_name = host_vars[
                'ansible_host'] if 'ansible_host' in host_vars.keys(
                ) else host.get_name()

            for play in playbook.get_plays():
                loader.set_vault_password(vault_pass)
                all_vars = variable_manager.get_vars(loader=loader,
                                                     play=play,
                                                     host=host)

                json_data[host_name] = all_vars['vars']

                json_data[host_name]['ansible_groups'] = all_vars[
                    'group_names']
                json_data[host_name]['ansible_roles'] = all_vars['role_names']

                for elem in ignored_elements:
                    del json_data['{}'.format(host)][elem]

                json_data[host_name][
                    'ansible_become_user'] = self.app.pargs.become_user

                if passwords['become_pass'] is not None:
                    json_data[host_name]['ansible_become_pass'] = passwords[
                        'become_pass']

                json_data[host_name]['ansible_become'] = self.app.pargs.become
                json_data[host_name][
                    'ansible_become_method'] = self.app.pargs.become_method

                if self.app.pargs.ssh_extra_args:
                    json_data[host_name][
                        'ansible_ssh_extra_args'] = self.app.pargs.ssh_extra_args

                if self.app.pargs.scp_extra_args:
                    json_data[host_name][
                        'ansible_scp_extra_args'] = self.app.pargs.scp_extra_args

                if self.app.pargs.sftp_extra_args:
                    json_data[host_name][
                        'ansible_sftp_extra_args'] = self.app.pargs.sftp_extra_args

                if self.app.pargs.ssh_common_args:
                    json_data[host_name][
                        'ansible_ssh_common_args'] = self.app.pargs.ssh_common_args

                json_data[host_name][
                    'ansible_connection_timeout'] = self.app.pargs.timeout
                json_data[host_name][
                    'ansible_connection_method'] = self.app.pargs.connection

                if self.app.pargs.private_key:
                    json_data[host_name][
                        'ansible_private_key'] = self.app.pargs.private_key

                json_data[host_name][
                    'ansible_ask_pass'] = self.app.pargs.ask_pass

                if self.app.pargs.limit:
                    json_data[host_name][
                        'ansible_limit'] = self.app.pargs.limit

                # FIXME: Extra vars needs to be processed by Ansible instead of dumping them
                # here as a "dumb" string.
                if self.app.pargs.extra_vars:
                    json_data[host_name][
                        'ansible_extra_vars'] = self.app.pargs.extra_vars

            for key, value in json_data[host_name].iteritems():
                if type(value) is AnsibleVaultEncryptedUnicode:
                    json_data[host_name][key] = str(value)

        # Convert the processed python dictionary to a valid json string
        json_obj = json.dumps(json_data)

        # Take the json string, and convert it to a valid yaml string
        yml = YAML(typ="safe", pure=True)
        yml.default_flow_style = False

        yml_obj = yml.load(json_obj)

        if self.app.pargs.output is None:
            yml.dump(yml_obj, sys.stdout)
        else:
            with open(self.app.pargs.output, 'w') as outfile:
                yml.dump(yml_obj, outfile)

            print(Fore.GREEN +
                  "Ansible variable dictionary written to {}".format(
                      self.app.pargs.output))

        sys.exit(1)