Esempio n. 1
0
    def get_play_prereqs_2(self, options):
        loader = DataLoader()

        if self.vault_pass:
            loader.set_vault_password(self.vault_pass)

        variable_manager = VariableManager()
        variable_manager.extra_vars = self.extra_vars
        variable_manager.options_vars = {
            'ansible_version': self.version_info(ansible_version)
        }

        # Add this to avoid the Ansible bug:  no host vars as host is not in inventory
        # In version 2.0.1 it must be fixed
        ansible.inventory.HOSTS_PATTERNS_CACHE = {}

        inventory = Inventory(loader=loader,
                              variable_manager=variable_manager,
                              host_list=options.inventory)
        variable_manager.set_inventory(inventory)

        if self.host:
            inventory.subset(self.host)
        # let inventory know which playbooks are using so it can know the
        # basedirs
        inventory.set_playbook_basedir(os.path.dirname(self.playbook_file))

        return loader, inventory, variable_manager
class Inventory24(Inventory):

    def __init__(self, inventory, ask_vault_pass, vault_password_files, vault_ids):
        from ansible.cli import CLI
        super(Inventory24, self).__init__()
        loader = DataLoader()
        if vault_ids or vault_password_files or ask_vault_pass:
            CLI.setup_vault_secrets(loader, vault_ids, vault_password_files, ask_vault_pass)
        self.inventory = ansible.inventory.manager.InventoryManager(loader=loader, sources=inventory)
        self.variable_manager = VariableManager(loader=loader)
        self.variable_manager.set_inventory(self.inventory)

    # internal fuctions that actually do the work
    # adapted almost entirely from lib/ansible/vars/manager.py
    def _plugins_inventory(self, entities):
        import os
        from ansible.plugins.loader import vars_loader
        from ansible.utils.vars import combine_vars
        ''' merges all entities by inventory source '''
        data = {}
        for inventory_dir in self.variable_manager._inventory._sources:
            if ',' in inventory_dir:  # skip host lists
                continue
            elif not os.path.isdir(inventory_dir):  # always pass 'inventory directory'
                inventory_dir = os.path.dirname(inventory_dir)

            for plugin in vars_loader.all():
                data = combine_vars(data, self._get_plugin_vars(plugin, inventory_dir, entities))
        return data

    def _get_plugin_vars(self, plugin, path, entities):
        from ansible.inventory.host import Host
        data = {}
        try:
            data = plugin.get_vars(self.variable_manager._loader, path, entities)
        except AttributeError:
            for entity in entities:
                if isinstance(entity, Host):
                    data.update(plugin.get_host_vars(entity.name))
                else:
                    data.update(plugin.get_group_vars(entity.name))
        return data

    def get_group_vars(self, group):
        return self._plugins_inventory([group])

    def get_host_vars(self, host):
        try:
            all_vars = self.variable_manager.get_vars(host=host, include_hostvars=True)
        except ansible.errors.AnsibleParserError:
            raise NoVaultSecretFound
        # play, host, task, include_hostvars, include_delegate_to
        magic_vars = ['ansible_playbook_python', 'groups', 'group_names', 'inventory_dir',
                      'inventory_file', 'inventory_hostname', 'inventory_hostname_short',
                      'omit', 'playbook_dir']
        return {k: v for (k, v) in all_vars.items() if k not in magic_vars}

    def get_group(self, group_name):
        return self.inventory.groups[group_name]
Esempio n. 3
0
def ansible_runner_24x(playbook_path,
                       module_path,
                       extra_var,
                       inventory_src,
                       console=True):
    loader = DataLoader()
    extra_var["ansible_python_interpreter"] = sys.executable
    variable_manager = VariableManager(loader=loader)
    variable_manager.extra_vars = extra_var
    inventory = Inventory(loader=loader, sources=[inventory_src])
    variable_manager.set_inventory(inventory)
    passwords = {}
    Options = namedtuple('Options', [
        'connection',
        'module_path',
        'forks',
        'become',
        'become_method',
        'become_user',
        'check',
        'diff',
        'listhosts',
        'listtasks',
        'listtags',
        'syntax',
        'remote_user',
        'private_key_file',
        'ssh_common_args',
        'ssh_extra_args',
        'sftp_extra_args',
        'scp_extra_args',
        'verbosity',
    ])
    options = Options(listtags=False,
                      listtasks=False,
                      listhosts=False,
                      syntax=False,
                      connection='local',
                      module_path=module_path,
                      forks=100,
                      remote_user='******',
                      private_key_file=None,
                      ssh_common_args=None,
                      ssh_extra_args=None,
                      sftp_extra_args=None,
                      scp_extra_args=None,
                      become=False,
                      become_method='sudo',
                      become_user='******',
                      verbosity=4,
                      diff=False,
                      check=False)
    pbex = PlaybookExecutor(playbooks=[playbook_path],
                            inventory=inventory,
                            variable_manager=variable_manager,
                            loader=loader,
                            options=options,
                            passwords=passwords)
    return pbex
Esempio n. 4
0
def main():
    host_list = ['localhost', 'www.example.com', 'www.google.com']
    Options = namedtuple('Options', ['connection', 'module_path', 'forks', 'remote_user',
                                     'private_key_file', 'ssh_common_args', 'ssh_extra_args', 'sftp_extra_args',
                                     'scp_extra_args', 'become', 'become_method', 'become_user', 'verbosity', 'check'])

    # initialize needed objects
    variable_manager = VariableManager()
    loader = DataLoader()
    options = Options(connection='smart', module_path='/usr/share/ansible', forks=100,
                      remote_user=None, private_key_file=None, ssh_common_args=None, ssh_extra_args=None,
                      sftp_extra_args=None, scp_extra_args=None, become=None, become_method=None,
                      become_user=None, verbosity=None, check=False)

    passwords = dict()

    # create inventory and pass to var manager
    inventory = Inventory(loader=loader, variable_manager=variable_manager, host_list=host_list)
    variable_manager.set_inventory(inventory)

    # create play with tasks
    play_source = dict(
        name="Ansible Play",
        hosts=host_list,
        gather_facts='no',
        tasks=[dict(action=dict(module='command', args=dict(cmd='/usr/bin/uptime')))]
    )
    play = Play().load(play_source, variable_manager=variable_manager, loader=loader)

    # actually run it
    tqm = None
    callback = ResultsCollector()
    try:
        tqm = TaskQueueManager(
            inventory=inventory,
            variable_manager=variable_manager,
            loader=loader,
            options=options,
            passwords=passwords,
        )
        tqm._stdout_callback = callback
        result = tqm.run(play)
    finally:
        if tqm is not None:
            tqm.cleanup()

    print("UP ***********")
    for host, result in callback.host_ok.items():
        print('{} >>> {}'.format(host, result._result['stdout']))

    print("FAILED *******")
    for host, result in callback.host_failed.items():
        print('{} >>> {}'.format(host, result._result['msg']))

    print("DOWN *********")
    for host, result in callback.host_unreachable.items():
        print('{} >>> {}'.format(host, result._result['msg']))
Esempio n. 5
0
    def __init__(self, **kwargs):
        super(Ansible_playbook, self).__init__(**kwargs)

        self.task_file = kwargs.get('task_file', None)
        self.sudo = kwargs.get('sudo', False)
        self.sudo_user = kwargs.get('sudo_user', False)
        self.sudo_password = kwargs.get('sudo_password', False)

        # check if parameters have been provided
        if self._is_parameters_ok():
            # since the API is constructed for CLI it expects certain options to always be set in the context object
            context.CLIARGS = self._get_options()

            # initialize needed objects
            loader = DataLoader()

            passwords = {'become_pass': self.sudo_password}

            inventory = InventoryManager(loader=loader, sources="localhost,")

            # variable manager takes care of merging all the different sources to give you a unified
            # view of variables available in each context
            variable_manager = VariableManager(loader=loader,
                                               inventory=inventory)
            variable_manager.set_inventory(inventory)

            playbooks = None
            with open(self.task_file, 'r') as stream:
                try:
                    playbooks = yaml.full_load(stream)
                except yaml.YAMLError as exc:
                    print(exc)

            play = Play().load(playbooks[0],
                               variable_manager=variable_manager,
                               loader=loader)

            # Run it - instantiate task queue manager, which takes care of forking and setting up all objects
            # to iterate over host list and tasks
            tqm = None
            try:
                tqm = TaskQueueManager(
                    inventory=inventory,
                    variable_manager=variable_manager,
                    loader=loader,
                    passwords=passwords,
                    stdout_callback='default',
                    # Use our custom callback instead of the ``default`` callback plugin, which prints to stdout
                )
                tqm.run(
                    play
                )  # most interesting data for a play is actually sent to the callback's methods
            finally:
                # we always need to cleanup child procs and the structres we use to communicate with them
                if tqm is not None:
                    tqm.cleanup()
Esempio n. 6
0
    def fetch_files(self):
        """
        Fetch files from all hosts via ansible playbook

        reference:
          https://docs.ansible.com/ansible/latest/dev_guide/developing_api.html
        """
        loader = DataLoader()
        inventory = InventoryManager(loader=loader, sources=[INVENTORY_PATH])

        variable_manager = VariableManager(
            loader=loader,
            inventory=inventory,
        )

        variable_manager.set_inventory(inventory)

        variable_manager.extra_vars = {
            "data_id": self.new_id,
            "data_path": self.data_path,
            "remote_path": REMOTE_DATA_PATH
        }

        Options = namedtuple("Options", [
            "connection", "forks", "become", "become_method", "become_user",
            "check", "listhosts", "listtasks", "listtags", "syntax",
            "module_path", "diff"
        ])

        options = Options(connection="ssh",
                          forks=100,
                          become=True,
                          become_method="sudo",
                          become_user="******",
                          check=False,
                          listhosts=False,
                          listtasks=False,
                          listtags=False,
                          syntax=False,
                          module_path="",
                          diff=False)

        passwords = dict(vault_pass="******")

        playbook = PlaybookExecutor(playbooks=[PLAYBOOK_PATH],
                                    inventory=inventory,
                                    loader=loader,
                                    variable_manager=variable_manager,
                                    options=options,
                                    passwords=passwords)
        if not self.ansible_stdout:
            results_callback = ResultCallback()
            playbook._tqm._stdout_callback = results_callback
        _.info("fetch_files started...")
        playbook.run()
Esempio n. 7
0
class PlaybookRunner(object):
    def __init__(self, playbook, extra_vars, check_mode=True, verbosity=0):
        self.extra_vars = extra_vars
        self.options = Options()
        self.options.verbosity = verbosity
        self.options.connection = 'local'  # Need a connection type "smart" or "ssh"
        self.options.become = True
        self.options.become_method = 'sudo'
        self.options.become_user = '******'
        self.options.check = check_mode

        # Set global verbosity
        self.display = Display()
        self.display.verbosity = self.options.verbosity
        # Executor appears to have it's own 
        # verbosity object/setting as well
        playbook_executor.verbosity = self.options.verbosity

        # Gets data from YAML/JSON files
        self.loader = DataLoader()
        # self.loader.set_vault_password(os.environ['VAULT_PASS'])

        # Set inventory, using most of above objects
        self.inventory = InventoryManager(loader=self.loader, sources="localhost,")
        # All the variables from all the various places
        self.variable_manager = VariableManager(loader=self.loader,
                                                inventory=self.inventory)

        self.variable_manager.set_inventory(self.inventory)
        self.variable_manager.extra_vars = self.extra_vars

        # Playbook to run. Assumes it is local to this python file
        pb_dir = os.path.dirname(__file__)
        playbook = "%s/%s" % (pb_dir, playbook)

        # Setup playbook executor, but don't run until run() called
        self.pbex = playbook_executor.PlaybookExecutor(
            playbooks=[playbook],
            inventory=self.inventory,
            variable_manager=self.variable_manager,
            loader=self.loader,
            options=self.options,
            passwords={})

    def run(self):
        # Results of PlaybookExecutor
        self.pbex.run()
        # noinspection PyProtectedMember
        stats = self.pbex._tqm._stats

        hosts = sorted(stats.processed.keys())
        for h in hosts:
            t = stats.summarize(h)
            if t['unreachable'] > 0 or t['failures'] > 0:
                raise Exception("Had some failure")
Esempio n. 8
0
def run_playbook(play: AnsiblePlay) -> int:
    """Run ansible playbook

    Args:
        play (AnsiblePlay): object describing the current play

    Returns:
        int: return code
    """
    if play.inventory:
        env = {"ANSIBLE_HOST_KEY_CHECKING": "False"}
        return execute_command(
            [
            "ansible-playbook",
            "-i",
            play.inventory,
            "-e",
            json.dumps(play.extra_vars),
            "--tags",
            ",".join(play.tags),
            play.playbook,
            ], env=env,
        )

    context.CLIARGS = ImmutableDict(
        tags=play.tags,
        skip_tags=play.skip_tags,
        connection='smart',
        verbosity=play.verbosity,
        forks=10,
        become=None,
        become_method=None,
        become_user=None,
        check=False,
        syntax=None,
        start_at_task=None,
        diff=False,
    )
    loader = DataLoader()
    variable_manager = VariableManager(loader=loader)
    variable_manager.extra_vars.update(play.extra_vars)
    inventory = InventoryManager(loader=loader)
    variable_manager.set_inventory(inventory)
    passwords = {}
    pbex = PlaybookExecutor(
        playbooks=[play.playbook],
        inventory=inventory,
        variable_manager=variable_manager,
        loader=loader,
        passwords=passwords,
    )
    return pbex.run()
Esempio n. 9
0
def hostsPlaybook(hosts_path, playbook_path):
    # 用来加载解析yaml文件或JSON内容,并且支持vault的解密
    loader = DataLoader()
    inventory = InventoryManager(loader=loader, sources=hosts_path)
    # 管理变量的类,包括主机,组,扩展等变量,之前版本是在 inventory中的
    variable_manager = VariableManager(loader=loader, inventory=inventory)
    # 把inventory传递给variable_manager管理
    variable_manager.set_inventory(inventory)

    runner = PlayBookRunner(playbook_path, inventory=inventory)

    ret = runner.run()
    return ret
Esempio n. 10
0
    def _run_play(self, play_source, host_vars):
        host_list = play_source['hosts']

        loader = dataloader.DataLoader()

        # FIXME(jpena): we need to behave differently if we are using
        # Ansible >= 2.4.0.0. Remove when only versions > 2.4 are supported
        if PRE_24_ANSIBLE:
            variable_manager = VariableManager()
            inventory_inst = Inventory(loader=loader,
                                       variable_manager=variable_manager,
                                       host_list=host_list)
            variable_manager.set_inventory(inventory_inst)
        else:
            inventory_inst = Inventory(loader=loader,
                                       sources=','.join(host_list) + ',')
            variable_manager = VariableManager(loader=loader,
                                               inventory=inventory_inst)

        for host, variables in host_vars.items():
            host_inst = inventory_inst.get_host(host)
            for var_name, value in variables.items():
                if value is not None:
                    variable_manager.set_host_variable(
                        host_inst, var_name, value)

        storage = []
        callback = MyCallback(storage)

        tqm = task_queue_manager.TaskQueueManager(
            inventory=inventory_inst,
            variable_manager=variable_manager,
            loader=loader,
            options=self.options,
            passwords=self.passwords,
            stdout_callback=callback,
        )

        # create play
        play_inst = play.Play().load(play_source,
                                     variable_manager=variable_manager,
                                     loader=loader)

        # actually run it
        try:
            tqm.run(play_inst)
        finally:
            tqm.cleanup()

        return storage
Esempio n. 11
0
def ansible_runner_24x(playbook_path,
                       extra_vars,
                       options,
                       inventory_src='localhost',
                       console=True):

    loader = DataLoader()
    variable_manager = VariableManager(loader=loader)
    variable_manager._extra_vars = extra_vars
    inventory = Inventory(loader=loader, sources=[inventory_src])
    variable_manager.set_inventory(inventory)
    passwords = {}

    pbex = PlaybookExecutor([playbook_path], inventory, variable_manager,
                            loader, options, passwords)
    return pbex
Esempio n. 12
0
class Inventory20(Inventory):
    def __init__(self, inventory, ask_vault_pass, vault_password_files,
                 vault_ids):
        if vault_ids or len(vault_password_files) > 1:
            raise NotImplementedError
        from ansible.cli import CLI
        super(Inventory20, self).__init__()
        loader = DataLoader()
        if ask_vault_pass:
            self.vault_pass = CLI.ask_vault_passwords()
        elif vault_password_files:
            self.vault_pass = CLI.read_vault_password_file(
                vault_password_files[0], loader)
        if self.vault_pass is not None:
            loader.set_vault_password(self.vault_pass)
        self.variable_manager = VariableManager()
        try:
            self.inventory = ansible.inventory.Inventory(
                loader=loader,
                variable_manager=self.variable_manager,
                host_list=inventory)
        except ansible.errors.AnsibleError:
            raise NoVaultSecretFound
        self.variable_manager.set_inventory(self.inventory)

    def _handle_missing_return_result(self, fn, member):
        import inspect
        # http://stackoverflow.com/a/197053
        vars = inspect.getargspec(fn)
        if 'return_results' in vars[0]:
            return fn(member, return_results=True)
        else:
            return fn(member)

    def get_group_vars(self, group):
        return self._handle_missing_return_result(
            self.inventory.get_group_vars, group)

    def get_host_vars(self, host):
        return self._handle_missing_return_result(self.inventory.get_host_vars,
                                                  host)

    def get_group(self, group_name):
        return self.inventory.get_group(group_name)
Esempio n. 13
0
def ansible_runner_24x(playbook_path,
                       extra_vars,
                       options=None,
                       inventory_src='localhost',
                       console=True):

    loader = DataLoader()
    variable_manager = VariableManager(loader=loader)
    variable_manager.extra_vars = extra_vars
    inventory = Inventory(loader=loader, sources=[inventory_src])
    variable_manager.set_inventory(inventory)
    passwords = {}

    pbex = PlaybookExecutor([playbook_path],
                            inventory,
                            variable_manager,
                            loader,
                            options,
                            passwords)
    return pbex
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(loader=loader)
    inventory = InventoryManager(loader=loader, sources='localhost,')
    variable_manager.set_inventory(inventory)

    return PlaybookExecutor(playbooks=playbook_files, inventory=inventory,
                            variable_manager=variable_manager, loader=loader,
                            options=options, passwords={})
class Inventory20(Inventory):

    def __init__(self, inventory, ask_vault_pass, vault_password_files, vault_ids):
        if vault_ids or len(vault_password_files) > 1:
            raise NotImplementedError
        from ansible.cli import CLI
        super(Inventory20, self).__init__()
        loader = DataLoader()
        if ask_vault_pass:
            self.vault_pass = CLI.ask_vault_passwords()
        elif vault_password_files:
            self.vault_pass = CLI.read_vault_password_file(vault_password_files[0], loader)
        if self.vault_pass is not None:
            loader.set_vault_password(self.vault_pass)
        self.variable_manager = VariableManager()
        try:
            self.inventory = ansible.inventory.Inventory(loader=loader,
                                                         variable_manager=self.variable_manager,
                                                         host_list=inventory)
        except ansible.errors.AnsibleError:
            raise NoVaultSecretFound
        self.variable_manager.set_inventory(self.inventory)

    def _handle_missing_return_result(self, fn, member):
        import inspect
        # http://stackoverflow.com/a/197053
        vars = inspect.getargspec(fn)
        if 'return_results' in vars[0]:
            return fn(member, return_results=True)
        else:
            return fn(member)

    def get_group_vars(self, group):
        return self._handle_missing_return_result(self.inventory.get_group_vars, group)

    def get_host_vars(self, host):
        return self._handle_missing_return_result(self.inventory.get_host_vars, host)

    def get_group(self, group_name):
        return self.inventory.get_group(group_name)
Esempio n. 16
0
    def get_play_prereqs_2(self, options):
        loader = DataLoader()

        if self.vault_pass:
            loader.set_vault_password(self.vault_pass)

        variable_manager = VariableManager()
        variable_manager.extra_vars = self.extra_vars
        variable_manager.options_vars = {
            'ansible_version': self.version_info(ansible_version)
        }

        inventory = Inventory(loader=loader,
                              variable_manager=variable_manager,
                              host_list=options.inventory)
        variable_manager.set_inventory(inventory)

        # let inventory know which playbooks are using so it can know the
        # basedirs
        inventory.set_playbook_basedir(os.path.dirname(self.playbook_file))

        return loader, inventory, variable_manager
class Runner(object):
    def __init__(self,
                 hostnames,
                 playbook,
                 private_key_file,
                 run_data,
                 become_pass,
                 verbosity=0):

        self.run_data = run_data

        self.options = Options()
        self.options.private_key_file = private_key_file
        self.options.verbosity = verbosity
        self.options.connection = 'ssh'  # Need a connection type "smart" or "ssh"
        self.options.become = True
        self.options.become_method = 'sudo'
        self.options.become_user = '******'

        # Set global verbosity
        self.display = Display()
        self.display.verbosity = self.options.verbosity
        # Executor appears to have it's own
        # verbosity object/setting as well
        playbook_executor.verbosity = self.options.verbosity

        # Become Pass Needed if not logging in as user root
        passwords = {'become_pass': become_pass}

        # Gets data from YAML/JSON files
        self.loader = DataLoader()
        self.loader.set_vault_password(os.environ['VAULT_PASS'])

        # All the variables from all the various places
        self.variable_manager = VariableManager()
        self.variable_manager.extra_vars = self.run_data

        # Parse hosts, I haven't found a good way to
        # pass hosts in without using a parsed template :(
        # (Maybe you know how?)
        self.hosts = NamedTemporaryFile(delete=False)
        self.hosts.write("""[run_hosts]
%s
""" % hostnames)
        self.hosts.close()

        # This was my attempt to pass in hosts directly.
        #
        # Also Note: In py2.7, "isinstance(foo, str)" is valid for
        #            latin chars only. Luckily, hostnames are
        #            ascii-only, which overlaps latin charset
        ## if isinstance(hostnames, str):
        ##     hostnames = {"customers": {"hosts": [hostnames]}}

        # Set inventory, using most of above objects
        self.inventory = Inventory(loader=self.loader,
                                   variable_manager=self.variable_manager,
                                   host_list=self.hosts.name)
        self.variable_manager.set_inventory(self.inventory)

        # Playbook to run. Assumes it is
        # local to this python file
        pb_dir = os.path.dirname(__file__)
        playbook = "%s/%s" % (pb_dir, playbook)

        # Setup playbook executor, but don't run until run() called
        self.pbex = playbook_executor.PlaybookExecutor(
            playbooks=[playbook],
            inventory=self.inventory,
            variable_manager=self.variable_manager,
            loader=self.loader,
            options=self.options,
            passwords=passwords)

    def run(self):
        # Results of PlaybookExecutor
        self.pbex.run()
        stats = self.pbex._tqm._stats

        # Test if success for record_logs
        run_success = True
        hosts = sorted(stats.processed.keys())
        for h in hosts:
            t = stats.summarize(h)
            if t['unreachable'] > 0 or t['failures'] > 0:
                run_success = False

        # Dirty hack to send callback to save logs with data we want
        # Note that function "record_logs" is one I created and put into
        # the playbook callback file
        self.pbex._tqm.send_callback('record_logs',
                                     user_id=self.run_data['user_id'],
                                     success=run_success)
Esempio n. 18
0
class AnsibleAPI(object):
    """
    This is a General object for parallel execute modules.
    """
    def __init__(self, resource, *args, **kwargs):
        self.resource = resource
        self.inventory = None
        self.variable_manager = None
        self.loader = None
        self.options = None
        self.passwords = None
        self.callback = None
        self.__initializeData()
        self.results_raw = {}

    def __initializeData(self):
        """
        初始化ansible
        """
        Options = namedtuple('Options', [
            'connection', 'module_path', 'forks', 'timeout', 'remote_user',
            'ask_pass', 'private_key_file', 'ssh_common_args',
            'ssh_extra_args', 'sftp_extra_args', 'scp_extra_args', 'become',
            'become_method', 'become_user', 'ask_value_pass', 'verbosity',
            'check', 'listhosts', 'listtasks', 'listtags', 'syntax'
        ])

        # initialize needed objects
        self.variable_manager = VariableManager()
        self.loader = DataLoader()
        self.options = Options(connection='smart',
                               module_path='/usr/share/ansible',
                               forks=100,
                               timeout=10,
                               remote_user='******',
                               ask_pass=False,
                               private_key_file=None,
                               ssh_common_args=None,
                               ssh_extra_args=None,
                               sftp_extra_args=None,
                               scp_extra_args=None,
                               become=None,
                               become_method=None,
                               become_user='******',
                               ask_value_pass=False,
                               verbosity=None,
                               check=False,
                               listhosts=False,
                               listtasks=False,
                               listtags=False,
                               syntax=False)

        self.passwords = dict(sshpass=None, becomepass=None)
        self.inventory = MyInventory(self.resource, self.loader,
                                     self.variable_manager).inventory
        self.variable_manager.set_inventory(self.inventory)

    def run(self, host_list, module_name, module_args):
        """
        run module from andible ad-hoc.
        module_name: ansible module_name
        module_args: ansible module args
        """
        # create play with tasks
        play_source = dict(
            name="Ansible Play",
            hosts=host_list,
            gather_facts='no',
            tasks=[dict(action=dict(module=module_name, args=module_args))])
        play = Play().load(play_source,
                           variable_manager=self.variable_manager,
                           loader=self.loader)

        # actually run it
        tqm = None
        self.callback = ResultsCollector()
        try:
            tqm = TaskQueueManager(
                inventory=self.inventory,
                variable_manager=self.variable_manager,
                loader=self.loader,
                options=self.options,
                passwords=self.passwords,
            )
            tqm._stdout_callback = self.callback
            tqm.run(play)
        finally:
            if tqm is not None:
                tqm.cleanup()

    def run_playbook(self, host_list, role_name, role_uuid, temp_param):
        """
        run ansible palybook
        """
        try:
            self.callback = ResultsCollector()
            filenames = ['' + '/handlers/ansible/v1_0/sudoers.yml'
                         ]  # playbook的路径
            template_file = ''  # 模板文件的路径
            if not os.path.exists(template_file):
                sys.exit()

            extra_vars = {
            }  # 额外的参数 sudoers.yml以及模板中的参数,它对应ansible-playbook test.yml --extra-vars "host='aa' name='cc' "
            host_list_str = ','.join([item for item in host_list])
            extra_vars['host_list'] = host_list_str
            extra_vars['username'] = role_name
            extra_vars['template_dir'] = template_file
            extra_vars['command_list'] = temp_param.get('cmdList')
            extra_vars['role_uuid'] = 'role-%s' % role_uuid
            self.variable_manager.extra_vars = extra_vars
            # actually run it
            executor = PlaybookExecutor(
                playbooks=filenames,
                inventory=self.inventory,
                variable_manager=self.variable_manager,
                loader=self.loader,
                options=self.options,
                passwords=self.passwords,
            )
            executor._tqm._stdout_callback = self.callback
            executor.run()
        except Exception as e:
            print('error: %s' % e)

    def get_result(self):
        self.results_raw = {'success': {}, 'failed': {}, 'unreachable': {}}
        for host, result in self.callback.host_ok.items():
            self.results_raw['success'][host] = result._result

        for host, result in self.callback.host_failed.items():
            self.results_raw['failed'][host] = result._result.get(
                'msg') or result._result

        for host, result in self.callback.host_unreachable.items():
            self.results_raw['unreachable'][host] = result._result['msg']

        return self.results_raw
Esempio n. 19
0
def run_playbook(playbook, host_list, vars):
    # https://github.com/celery/billiard/issues/189
    # https://github.com/Mirantis/kostyor-openstack-ansible/commit/407ec033514600cd62f4931f199efd13405b0aae
    import multiprocessing
    import billiard
    multiprocessing.Process = billiard.Process

    Options = namedtuple('Options', [
        'listtags', 'listtasks', 'listhosts', 'syntax', 'connection',
        'module_path', 'forks', 'remote_user', 'private_key_file',
        'ssh_common_args', 'ssh_extra_args', 'sftp_extra_args',
        'scp_extra_args', 'become', 'become_method', 'become_user',
        'verbosity', 'check', 'diff'
    ])
    loader = DataLoader()
    variable_manager = VariableManager(loader=loader)

    options = Options(listtags=False,
                      listtasks=False,
                      listhosts=False,
                      syntax=False,
                      connection='ssh',
                      module_path=None,
                      forks=100,
                      remote_user=None,
                      private_key_file=None,
                      ssh_common_args=None,
                      ssh_extra_args=None,
                      sftp_extra_args=None,
                      scp_extra_args=None,
                      become=False,
                      become_method='sudo',
                      become_user='******',
                      verbosity=None,
                      check=False,
                      diff=False)
    passwords = {}

    inventory = InventoryManager(loader=loader)
    inventory.add_group('ci')
    inventory.add_host(host_list.values()[0], 'ci')
    inventory.reconcile_inventory()

    variable_manager.set_inventory(inventory)
    variable_manager.extra_vars = vars
    playbook_path = playbook

    constants.HOST_KEY_CHECKING = False

    pbex = PlaybookExecutor(playbooks=[playbook_path],
                            inventory=inventory,
                            variable_manager=variable_manager,
                            loader=loader,
                            options=options,
                            passwords=passwords)

    results = pbex.run()
    pubkey = None
    try:
        pubkey = variable_manager._nonpersistent_fact_cache[
            host_list['ci']]['pubkey']['stdout']
    except KeyError:
        pass
    return results, pubkey
Esempio n. 20
0
class PlayBookJob(object):
    '''封装一个playbook接口,提供给外部使用'''
    def __init__(self,
                 playbooks,
                 ssh_user='******',
                 passwords='null',
                 project_name='all',
                 ack_pass=False,
                 forks=5,
                 ext_vars=None):
        self.playbooks = playbooks
        # self.host_list = host_list
        self.ssh_user = ssh_user
        self.passwords = dict(vault_pass=passwords)
        self.project_name = project_name
        self.ack_pass = ack_pass
        self.forks = forks
        self.connection = 'smart'
        self.ext_vars = ext_vars

        ## 用来加载解析yaml文件或JSON内容,并且支持vault的解密
        self.loader = DataLoader()

        # 根据inventory加载对应变量
        self.inventory = InventoryManager(loader=self.loader,
                                          sources=['/etc/ansible/hosts'])

        # 管理变量的类,包括主机,组,扩展等变量,之前版本是在 inventory中的
        self.variable_manager = VariableManager(loader=self.loader,
                                                inventory=self.inventory)
        self.variable_manager.extra_vars = self.ext_vars
        # print(self.variable_manager.get_vars())
        # print(self.variable_manager.get_vars()) # 所有主机信息

        self.variable_manager.set_inventory(self.inventory)

        # 初始化需要的对象1
        self.Options = namedtuple('Options', [
            'connection', 'remote_user', 'ask_sudo_pass', 'verbosity',
            'ack_pass', 'module_path', 'forks', 'become', 'become_method',
            'become_user', 'check', 'listhosts', 'listtasks', 'listtags',
            'syntax', 'sudo_user', 'sudo', 'diff'
        ])

        # 初始化需要的对象2
        self.options = self.Options(connection=self.connection,
                                    remote_user=self.ssh_user,
                                    ack_pass=self.ack_pass,
                                    sudo_user=self.ssh_user,
                                    forks=self.forks,
                                    sudo='yes',
                                    ask_sudo_pass=False,
                                    verbosity=5,
                                    module_path=None,
                                    become=True,
                                    become_method='sudo',
                                    become_user='******',
                                    check=None,
                                    listhosts=None,
                                    listtasks=None,
                                    listtags=None,
                                    syntax=None,
                                    diff=False)

        # 初始化console输出
        self.callback = ResultCallback()

        # 直接开始
        # return self.run()

    def get_result(self):
        # print(dir(self.callback))
        # print("host_ok:", self.callback.host_ok)
        return self.callback.host_ok

    # def get_result(self):
    # self.result_all = {'success': {}, 'fail': {}, 'unreachable': {}}
    # # print result_all
    # # print dir(self.results_callback)
    # for host, result in self.results_callback.host_ok.items():
    #     self.result_all['success'][host] = result._result
    #
    # for host, result in self.results_callback.host_failed.items():
    #     self.result_all['failed'][host] = result._result['msg']
    #
    # for host, result in self.results_callback.host_unreachable.items():
    #     self.result_all['unreachable'][host] = result._result['msg']
    #
    # for i in self.result_all['success'].keys():
    #     print(i, self.result_all['success'][i])
    # self.result_msg = self.callback.v2_runner_item_on_ok()
    # return self.result_msg

    # print(self.result_all['fail'])
    # print(self.result_all['unreachable'])

    def run(self):
        # pb = None
        pb = YunweiPlaybookExecutor(playbooks=self.playbooks,
                                    inventory=self.inventory,
                                    variable_manager=self.variable_manager,
                                    loader=self.loader,
                                    options=self.options,
                                    passwords=self.passwords,
                                    stdout_callback=self.callback)

        # pb._tqm._stdout_callback = self.callback

        pb.run()
        del pb

        return self.get_result()
Esempio n. 21
0
    def test_variable_manager_precedence(self):
        # FIXME: this needs to be redone as dataloader is not the automatic source of data anymore
        return

        # pylint: disable=unreachable
        '''
        Tests complex variations and combinations of get_vars() with different
        objects to modify the context under which variables are merged.
        '''
        # FIXME: BCS makethiswork
        # return True

        mock_inventory = MagicMock()

        inventory1_filedata = """
            [group2:children]
            group1

            [group1]
            host1 host_var=host_var_from_inventory_host1

            [group1:vars]
            group_var = group_var_from_inventory_group1

            [group2:vars]
            group_var = group_var_from_inventory_group2
            """

        fake_loader = DictDataLoader({
            # inventory1
            '/etc/ansible/inventory1':
            inventory1_filedata,
            # role defaults_only1
            '/etc/ansible/roles/defaults_only1/defaults/main.yml':
            """
            default_var: "default_var_from_defaults_only1"
            host_var: "host_var_from_defaults_only1"
            group_var: "group_var_from_defaults_only1"
            group_var_all: "group_var_all_from_defaults_only1"
            extra_var: "extra_var_from_defaults_only1"
            """,
            '/etc/ansible/roles/defaults_only1/tasks/main.yml':
            """
            - debug: msg="here i am"
            """,

            # role defaults_only2
            '/etc/ansible/roles/defaults_only2/defaults/main.yml':
            """
            default_var: "default_var_from_defaults_only2"
            host_var: "host_var_from_defaults_only2"
            group_var: "group_var_from_defaults_only2"
            group_var_all: "group_var_all_from_defaults_only2"
            extra_var: "extra_var_from_defaults_only2"
            """,
        })

        inv1 = InventoryManager(loader=fake_loader,
                                sources=['/etc/ansible/inventory1'])
        v = VariableManager(inventory=mock_inventory, loader=fake_loader)

        play1 = Play.load(dict(
            hosts=['all'],
            roles=['defaults_only1', 'defaults_only2'],
        ),
                          loader=fake_loader,
                          variable_manager=v)

        # first we assert that the defaults as viewed as a whole are the merged results
        # of the defaults from each role, with the last role defined "winning" when
        # there is a variable naming conflict
        res = v.get_vars(play=play1)
        self.assertEqual(res['default_var'], 'default_var_from_defaults_only2')

        # next, we assert that when vars are viewed from the context of a task within a
        # role, that task will see its own role defaults before any other role's
        blocks = play1.compile()
        task = blocks[1].block[0]
        res = v.get_vars(play=play1, task=task)
        self.assertEqual(res['default_var'], 'default_var_from_defaults_only1')

        # next we assert the precedence of inventory variables
        v.set_inventory(inv1)
        h1 = inv1.get_host('host1')

        res = v.get_vars(play=play1, host=h1)
        self.assertEqual(res['group_var'], 'group_var_from_inventory_group1')
        self.assertEqual(res['host_var'], 'host_var_from_inventory_host1')

        # next we test with group_vars/ files loaded
        fake_loader.push(
            "/etc/ansible/group_vars/all", """
        group_var_all: group_var_all_from_group_vars_all
        """)
        fake_loader.push(
            "/etc/ansible/group_vars/group1", """
        group_var: group_var_from_group_vars_group1
        """)
        fake_loader.push(
            "/etc/ansible/group_vars/group3", """
        # this is a dummy, which should not be used anywhere
        group_var: group_var_from_group_vars_group3
        """)
        fake_loader.push(
            "/etc/ansible/host_vars/host1", """
        host_var: host_var_from_host_vars_host1
        """)
        fake_loader.push(
            "group_vars/group1", """
        playbook_group_var: playbook_group_var
        """)
        fake_loader.push(
            "host_vars/host1", """
        playbook_host_var: playbook_host_var
        """)

        res = v.get_vars(play=play1, host=h1)
        # self.assertEqual(res['group_var'], 'group_var_from_group_vars_group1')
        # self.assertEqual(res['group_var_all'], 'group_var_all_from_group_vars_all')
        # self.assertEqual(res['playbook_group_var'], 'playbook_group_var')
        # self.assertEqual(res['host_var'], 'host_var_from_host_vars_host1')
        # self.assertEqual(res['playbook_host_var'], 'playbook_host_var')

        # add in the fact cache
        v._fact_cache['host1'] = dict(
            fact_cache_var="fact_cache_var_from_fact_cache")

        res = v.get_vars(play=play1, host=h1)
        self.assertEqual(res['fact_cache_var'],
                         'fact_cache_var_from_fact_cache')
Esempio n. 22
0
class Inventory24(Inventory):
    def __init__(self, inventory, ask_vault_pass, vault_password_files,
                 vault_ids):
        from ansible.cli import CLI
        super(Inventory24, self).__init__()
        loader = DataLoader()
        if vault_ids or vault_password_files or ask_vault_pass:
            CLI.setup_vault_secrets(loader, vault_ids, vault_password_files,
                                    ask_vault_pass)
        self.inventory = ansible.inventory.manager.InventoryManager(
            loader=loader, sources=inventory)
        self.variable_manager = VariableManager(loader=loader)
        self.variable_manager.set_inventory(self.inventory)

    # internal fuctions that actually do the work
    # adapted almost entirely from lib/ansible/vars/manager.py
    def _plugins_inventory(self, entities):
        import os
        from ansible.plugins.loader import vars_loader
        from ansible.utils.vars import combine_vars
        ''' merges all entities by inventory source '''
        data = {}
        for inventory_dir in self.variable_manager._inventory._sources:
            if ',' in inventory_dir:  # skip host lists
                continue
            elif not os.path.isdir(
                    inventory_dir):  # always pass 'inventory directory'
                inventory_dir = os.path.dirname(inventory_dir)

            for plugin in vars_loader.all():
                data = combine_vars(
                    data, self._get_plugin_vars(plugin, inventory_dir,
                                                entities))
        return data

    def _get_plugin_vars(self, plugin, path, entities):
        from ansible.inventory.host import Host
        data = {}
        try:
            data = plugin.get_vars(self.variable_manager._loader, path,
                                   entities)
        except AttributeError:
            for entity in entities:
                if isinstance(entity, Host):
                    data.update(plugin.get_host_vars(entity.name))
                else:
                    data.update(plugin.get_group_vars(entity.name))
        return data

    def get_group_vars(self, group):
        return self._plugins_inventory([group])

    def get_host_vars(self, host):
        try:
            all_vars = self.variable_manager.get_vars(host=host,
                                                      include_hostvars=True)
        except ansible.errors.AnsibleParserError:
            raise NoVaultSecretFound
        # play, host, task, include_hostvars, include_delegate_to
        magic_vars = [
            'ansible_playbook_python', 'groups', 'group_names',
            'inventory_dir', 'inventory_file', 'inventory_hostname',
            'inventory_hostname_short', 'omit', 'playbook_dir'
        ]
        return {k: v for (k, v) in all_vars.items() if k not in magic_vars}

    def get_group(self, group_name):
        return self.inventory.groups[group_name]
Esempio n. 23
0
class AnsibleController(object):
    """Ansible controller.

    The primary responsibility is for driving the execution of either modules
    or playbooks to configure/manage remote machines.
    """
    def __init__(self, inventory):
        """Constructor.

        Primarily used for initializing attributes used by module/playbook
        execution.

        :param inventory: inventory file
        """
        self.loader = DataLoader()
        self.ansible_inventory = inventory
        self.inventory = None
        self.variable_manager = None

        # module options
        self.module_options = namedtuple('Options', [
            'connection', 'module_path', 'forks', 'become', 'become_method',
            'become_user', 'check', 'remote_user', 'private_key_file', 'diff'
        ])

    def set_inventory(self):
        """Create the ansible inventory object with the supplied inventory."""
        self.variable_manager = VariableManager(loader=self.loader)
        self.inventory = InventoryManager(loader=self.loader,
                                          sources=self.ansible_inventory)
        self.variable_manager.set_inventory(self.inventory)

    @ssh_retry
    def run_module(self,
                   module,
                   logger,
                   script=None,
                   run_options={},
                   extra_args=None,
                   extra_vars=None,
                   ans_verbosity=None):
        """

        :param module: Name of the ansible module to run.
        :type module: str
        :param logger: Logger object.
        :type logger: logger object
        :param script: Absolute path a script, if using the script module.
        :type script: str
        :param run_options: additional ansible run options
        :type run_options: dict
        :param extra_args: module arguments
        :type extra_args: str
        :param extra_vars: used to determine where to run the module against
        :type extra_vars: dict
        :param ans_verbosity: verbosity to use for the ansible call.
        :type ans_verbosity: str
        :return: A tuple (rc, sterr)
        """

        if "localhost" in extra_vars and extra_vars["localhost"]:
            module_call = "ansible localhost -m %s" % (module)
        else:
            module_call = "ansible -i %s %s -m %s" % \
                          (self.ansible_inventory, extra_vars["hosts"], module)

        # add extra arguments
        if module == "script" or module == "shell":
            if extra_args:
                module_call += " -a '%s %s'" % (script, extra_args)
            else:
                module_call += " -a '%s'" % script
        elif extra_args:
            module_call += " -a '%s'" % extra_args

        if run_options:
            for key in run_options:
                if key == "remote_user":
                    module_call += " --user %s" % run_options[key]
                elif key == "become":
                    if run_options[key]:
                        module_call += " --%s" % key
                elif key == "tags":
                    taglist = ','.join(run_options[key])
                    module_call += " --tags %s" % taglist
                else:
                    module_call += " --%s %s" % (key.replace(
                        '_', '-'), run_options[key])

        if ans_verbosity:
            module_call += " -%s" % ans_verbosity

        # Set the connection if localhost
        if "localhost" in extra_vars and extra_vars["localhost"]:
            module_call += " -c local"

        logger.debug(module_call)
        output = exec_local_cmd_pipe(module_call, logger)
        return output

    @ssh_retry
    def run_playbook(self,
                     playbook,
                     logger,
                     extra_vars=None,
                     run_options=None,
                     ans_verbosity=None,
                     env_var=None):
        """Run an Ansible playbook.

        :param playbook: Playbook to call
        :type playbook: str
        :param extra_vars: Additional variables for playbook
        :type extra_vars: dict
        :param run_options: playbook run options
        :type run_options: dict
        :param ans_verbosity: ansible verbosity settings
        :param env_var: dict of env variables to be passed
        :type: env_var: dict
        :type ans_verbosity: str
        :return: A tuple (rc, sterr)
        """

        playbook_call = "ansible-playbook -i %s %s" % \
                        (self.ansible_inventory, playbook)
        if extra_vars is not None:
            for key in extra_vars:
                if not isinstance(extra_vars[key], string_types):
                    extra_var_dict = dict()
                    extra_var_dict[key] = extra_vars[key]
                    playbook_call += ' -e "%s" ' % extra_var_dict
                elif key == "file":
                    playbook_call += ' -e "@%s" ' % extra_vars[key]
                else:
                    playbook_call += " -e %s=\"'%s'\"" % (key, extra_vars[key])

        if run_options:
            for key in run_options:
                if key == "remote_user":
                    playbook_call += " --user %s" % run_options[key]
                elif key == "become":
                    if run_options[key]:
                        playbook_call += " --%s" % key
                elif key == "tags":
                    taglist = ','.join(run_options[key])
                    playbook_call += " --tags %s" % taglist
                elif key == "skip_tags":
                    taglist = ','.join(run_options[key])
                    playbook_call += " --skip-tags %s" % taglist
                elif key == "vault-password-file":
                    taglist = ','.join(run_options[key])
                    playbook_call += " --vault-password-file %s" % taglist
                else:
                    playbook_call += " --%s %s" % (key.replace(
                        '_', '-'), run_options[key])

        if ans_verbosity:
            playbook_call += " -%s" % ans_verbosity

        logger.debug(playbook_call)
        output = exec_local_cmd_pipe(playbook_call, logger, env_var=env_var)
        return output
    def test_variable_manager_precedence(self):
        # FIXME: this needs to be redone as dataloader is not the automatic source of data anymore
        return

        # pylint: disable=unreachable
        '''
        Tests complex variations and combinations of get_vars() with different
        objects to modify the context under which variables are merged.
        '''
        # FIXME: BCS makethiswork
        # return True

        mock_inventory = MagicMock()

        inventory1_filedata = """
            [group2:children]
            group1

            [group1]
            host1 host_var=host_var_from_inventory_host1

            [group1:vars]
            group_var = group_var_from_inventory_group1

            [group2:vars]
            group_var = group_var_from_inventory_group2
            """

        fake_loader = DictDataLoader({
            # inventory1
            '/etc/ansible/inventory1': inventory1_filedata,
            # role defaults_only1
            '/etc/ansible/roles/defaults_only1/defaults/main.yml': """
            default_var: "default_var_from_defaults_only1"
            host_var: "host_var_from_defaults_only1"
            group_var: "group_var_from_defaults_only1"
            group_var_all: "group_var_all_from_defaults_only1"
            extra_var: "extra_var_from_defaults_only1"
            """,
            '/etc/ansible/roles/defaults_only1/tasks/main.yml': """
            - debug: msg="here i am"
            """,

            # role defaults_only2
            '/etc/ansible/roles/defaults_only2/defaults/main.yml': """
            default_var: "default_var_from_defaults_only2"
            host_var: "host_var_from_defaults_only2"
            group_var: "group_var_from_defaults_only2"
            group_var_all: "group_var_all_from_defaults_only2"
            extra_var: "extra_var_from_defaults_only2"
            """,
        })

        inv1 = InventoryManager(loader=fake_loader, sources=['/etc/ansible/inventory1'])
        v = VariableManager(inventory=mock_inventory, loader=fake_loader)
        v._fact_cache = defaultdict(dict)

        play1 = Play.load(dict(
            hosts=['all'],
            roles=['defaults_only1', 'defaults_only2'],
        ), loader=fake_loader, variable_manager=v)

        # first we assert that the defaults as viewed as a whole are the merged results
        # of the defaults from each role, with the last role defined "winning" when
        # there is a variable naming conflict
        res = v.get_vars(play=play1)
        self.assertEqual(res['default_var'], 'default_var_from_defaults_only2')

        # next, we assert that when vars are viewed from the context of a task within a
        # role, that task will see its own role defaults before any other role's
        blocks = play1.compile()
        task = blocks[1].block[0]
        res = v.get_vars(play=play1, task=task)
        self.assertEqual(res['default_var'], 'default_var_from_defaults_only1')

        # next we assert the precedence of inventory variables
        v.set_inventory(inv1)
        h1 = inv1.get_host('host1')

        res = v.get_vars(play=play1, host=h1)
        self.assertEqual(res['group_var'], 'group_var_from_inventory_group1')
        self.assertEqual(res['host_var'], 'host_var_from_inventory_host1')

        # next we test with group_vars/ files loaded
        fake_loader.push("/etc/ansible/group_vars/all", """
        group_var_all: group_var_all_from_group_vars_all
        """)
        fake_loader.push("/etc/ansible/group_vars/group1", """
        group_var: group_var_from_group_vars_group1
        """)
        fake_loader.push("/etc/ansible/group_vars/group3", """
        # this is a dummy, which should not be used anywhere
        group_var: group_var_from_group_vars_group3
        """)
        fake_loader.push("/etc/ansible/host_vars/host1", """
        host_var: host_var_from_host_vars_host1
        """)
        fake_loader.push("group_vars/group1", """
        playbook_group_var: playbook_group_var
        """)
        fake_loader.push("host_vars/host1", """
        playbook_host_var: playbook_host_var
        """)

        res = v.get_vars(play=play1, host=h1)
        # self.assertEqual(res['group_var'], 'group_var_from_group_vars_group1')
        # self.assertEqual(res['group_var_all'], 'group_var_all_from_group_vars_all')
        # self.assertEqual(res['playbook_group_var'], 'playbook_group_var')
        # self.assertEqual(res['host_var'], 'host_var_from_host_vars_host1')
        # self.assertEqual(res['playbook_host_var'], 'playbook_host_var')

        # add in the fact cache
        v._fact_cache['host1'] = dict(fact_cache_var="fact_cache_var_from_fact_cache")

        res = v.get_vars(play=play1, host=h1)
        self.assertEqual(res['fact_cache_var'], 'fact_cache_var_from_fact_cache')
class Runner(object):

    def __init__(self, execution_id, playbook_dir, 
                 options, playbook_name, 
                 extra_vars, become_password=None):

        self.execution_id = execution_id
        self.extra_vars = extra_vars
        self.playbook_name = playbook_name
        self.options = Options()
        for k,v in options.iteritems():
            setattr(self.options, k,v)
        print options

        # Set global verbosity
        self.display = Display()
        self.display.verbosity = self.options.verbosity
        # Executor appears to have it's own 
        # verbosity object/setting as well
        playbook_executor.verbosity = self.options.verbosity

        # Become Pass Needed if not logging in as user root
        passwords = {'become_pass': become_password}

        # Gets data from YAML/JSON files
        self.loader = DataLoader()
        # Set inventory, using most of above objects
        temp_dir = "/home/pattabi/ansible/ansible_api_server/ansible_api_server/data"
        self.inventory = InventoryManager(loader=self.loader, sources=[temp_dir + "/" + "hosts"])

        # All the variables from all the various places
        self.variable_manager = VariableManager(loader=self.loader)
        self.variable_manager.set_inventory(self.inventory)
        self.variable_manager.extra_vars = self.extra_vars

        # Setup playbook executor, but don't run until run() called
        self.pbex = playbook_executor.PlaybookExecutor(
            playbooks=[playbook_dir + "/" + playbook_name], 
            inventory=self.inventory, 
            variable_manager=self.variable_manager,
            loader=self.loader, 
            options=self.options, 
            passwords=passwords)

    def run(self):
        # Results of PlaybookExecutor
        self.pbex.run()
        stats = self.pbex._tqm._stats

        # Test if success for record_logs
        run_success = True
        target_hosts = sorted(stats.processed.keys())
        for h in target_hosts:
            t = stats.summarize(h)
            if t['unreachable'] > 0 or t['failures'] > 0:
                run_success = False

        # Dirty hack to send callback to save logs with data we want
        # Note that function "record_logs" is one I created and put into
        # the playbook callback file
        self.pbex._tqm.send_callback(
            'record_logs', 
            self.execution_id,
            success=run_success
        )

        return stats
Esempio n. 26
0
class Runner(object):
    def __init__(self, tags, forks, *args, **kwargs):
        self._inventory = None
        self._variable_manager = None
        self._loader = None
        self._options = None
        self.passwords = None
        self.callback = None
        self.log_file_name = 'ansible.log'
        self.forks = forks
        self.tags = tags
        self._unreachable_hosts = dict()
        self.basepath = GET().get_log_dir()
        self.create_dir = CREATE()
        self.__initalizeData()

    def __initalizeData(self):
        '''
        初始化ansible
        '''
        Options = namedtuple('Options', [
            'connection',
            'remote_user',
            'ask_sudo_pass',
            'verbosity',
            'ack_pass',
            'module_path',
            'forks',
            'become',
            'become_method',
            'become_user',
            'check',
            'listhosts',
            'listtasks',
            'listtags',
            'syntax',
            'diff',
            'tags',
        ])
        self.options = Options(
            connection='smart',
            remote_user='******',
            ack_pass=None,
            forks=int(self.forks),
            ask_sudo_pass=False,
            verbosity=5,
            module_path=None,
            become=True,
            become_method='su',
            become_user='******',
            check=None,
            listhosts=False,
            listtasks=False,
            listtags=False,
            diff=False,
            syntax=None,
            tags=self.tags,
        )
        self.loader = DataLoader()
        self.variable_manager = VariableManager(loader=self.loader)
        self.config_items = Config_read()
        self.log_path = self.create_dir.create_dir(
            basepath=self.basepath,
            extra_path=self.config_items.get_value(sections='LOGGER_DIR',
                                                   key='ANSIBLE_LOG_FILE'))
        self.inventory = InventoryManager(
            loader=self.loader,
            sources=self.config_items.get_value(
                sections='ANSIBLE', key='INVENTORY_CONFIG').split(","))
        self.variable_manager.set_inventory(self.inventory)
        self.passwords = dict(conn_pass='******', become_pass='******')

    '''
    运行ansible adhoc
    '''

    def run(self, host_lists, module_name, module_args, register):
        self.logger = Logger(logger_name='ansible_adhoc',
                             external_path=self.log_path)
        self.callback = ResultsCollector()
        play_source = dict(name='Ansible Play',
                           hosts=host_lists,
                           gather_facts='no',
                           tasks=[
                               dict(action=dict(module=module_name,
                                                args=module_args),
                                    register=register)
                           ])
        play = Play().load(play_source,
                           variable_manager=self.variable_manager,
                           loader=self.loader)

        tqm = None
        try:
            tqm = TaskQueueManager(
                inventory=self.inventory,
                variable_manager=self.variable_manager,
                loader=self.loader,
                options=self.options,
                passwords=self.passwords,
                stdout_callback=self.callback,
            )
            result = tqm.run(play)
        except Exception as e:
            print e
            self.logger.error(message='Ansible adhoc error: %s' % e)
        finally:
            if tqm is not None:
                tqm.cleanup()

    '''
    运行ansible playbook
    '''

    def run_playbook(self, playbooks, ssh_user, project_name, extra_vars={}):
        try:
            self.playbookcallback = PlaybookResultsCollector()
            self.logger = Logger(logger_name='ansible_playbook',
                                 external_path=self.log_path)
            self.playbooks = playbooks
            if not os.path.exists(self.playbooks[0]):
                self.logger.error(message="Playbooks '%s' is not exist" %
                                  self.playbooks[0])
                sys.exit(1)
            else:
                self.logger.debug(message="Playbooks '%s' is exist" %
                                  self.playbooks[0])
            self.ssh_user = ssh_user
            self.project_name = project_name
            self.ack_pass = False
            self.connection = 'smart'
            self.extra_vars = extra_vars
            self.variable_manager.extra_vars = extra_vars

            pb = None
            pb = PlaybookExecutor(
                playbooks=self.playbooks,
                inventory=self.inventory,
                variable_manager=self.variable_manager,
                loader=self.loader,
                options=self.options,
                passwords=self.passwords,
                #tag                  = 'repo'
            )
            pb._tqm._stdout_callback = self.playbookcallback
            result = pb.run()
        except Exception as e:
            print e
            self.logger.critical(message="Ansilbe playbook error:%s" % e)

    def get_adhoc_message(self, status, host, result):
        self.status = 'Status:[%s]' % status
        self.host = ',Remote Host:[%s]' % host
        if result.get('start', None):
            self.start_time = result['start']
        else:
            self.start_time = None
        if result.get('end', None):
            self.end_time = result['end']
        else:
            self.end_time = None
        if self.start_time is not None and self.end_time is not None:
            self.period = ',Period:[%s - %s]' % (self.start_time,
                                                 self.end_time)
        else:
            self.period = ''
        if result.get('cmd', None):
            self.command = 'Command:[%s]' % result['cmd']
        else:
            self.command = ''
        if result.get('msg', None):
            return_data = result.get('msg').replace("\r\n", ",")
        elif result.get('stdout', None):
            return_data = result.get('stdout').replace("\n", ",")
        elif result.get('stderr', None):
            return_data = result.get('stderr').replace("\n", ",")
        else:
            return_data = result.get('stdout').replace("\n", ",")
        self.return_data = ',Result:[%s]' % return_data
        self.message = self.status + self.host + self.period + self.command + self.return_data
        return self.message

    def get_playbook_message(self, status, host, result):
        self.status = 'Status:[%s]' % status
        self.host = ',Remote Host:[%s]' % host
        if result.get('msg', None):
            self.msg = ',Msg:[%s]' % result['msg'].replace("\r\n", ",")
        else:
            self.msg = ',Msg:[%s]' % result
        self.playbooks = ',Playbook:[%s]' % self.playbooks[0]
        self.message = self.status + self.host + self.playbooks + self.msg
        return self.message

    '''
    将callback返回的ansible执行结果,打印成日志条目
    '''

    def get_adhoc_result(self):
        self.result_raw = {'Ok': {}, 'Failures': {}, 'Unreachable': {}}
        for host, result in self.callback.host_ok.items():
            status = 'Ok'
            self.get_adhoc_message(status, host, result)
            self.result_raw['Ok'][host] = result
            self.logger.info(message=self.message)
        for host, result in self.callback.host_failed.items():
            status = 'Failures'
            self.get_adhoc_message(status, host, result)
            self.result_raw['Failures'][host] = result
            self.logger.error(message=self.message)
        for host, result in self.callback.host_unreachable.items():
            print self.callback.host_unreachable
            status = 'Unreachable'
            self.get_adhoc_message(status, host, result)
            self.result_raw['Unreachable'][host] = result
            self.logger.error(message=self.message)

    def get_playbook_result(self):
        self.result_raw = {
            'Unreachable': {},
            'Skipped': {},
            'Ok': {},
            'Changed': {},
            'Failures': {}
        }
        for host, result in self.playbookcallback.task_ok.items():
            status = 'Ok'
            self.get_playbook_message(status, host, result)
            self.result_raw['Ok'][host] = result
            self.logger.info(message=self.message)

        for host, result in self.playbookcallback.task_skip.items():
            status = 'Skip'
            self.get_playbook_message(status, host, result)
            self.result_raw['Skip'][host] = result
            self.logger.info(message=self.message)

        for host, result in self.playbookcallback.task_failed.items():
            status = 'Failures'
            self.get_playbook_message(status, host, result)
            self.result_raw['Failures'][host] = result
            self.logger.error(message=self.message)

        for host, result in self.playbookcallback.task_unreachable.items():
            status = 'Unreachable'
            self.get_playbook_message(status, host, result)
            self.result_raw['Unreachable'][host] = result
            self.logger.error(message=self.message)
Esempio n. 27
0
class my_ansible_play():
    #这里是ansible运行
    #初始化各项参数,大部分都定义好,只有几个参数是必须要传入的
    def __init__(self,
                 playbooks,
                 ssh_user='******',
                 passwords='null',
                 project_name='all',
                 ack_pass=False,
                 forks=5,
                 ext_vars=None):
        self.playbooks = playbooks
        # self.host_list = host_list
        self.ssh_user = ssh_user
        self.passwords = dict(vault_pass=passwords)
        self.project_name = project_name
        self.ack_pass = ack_pass
        self.forks = forks
        self.connection = 'smart'
        self.ext_vars = ext_vars
        self.playbook_path = self.playbooks

        ## 用来加载解析yaml文件或JSON内容,并且支持vault的解密
        self.loader = DataLoader()

        # 根据inventory加载对应变量
        self.inventory = InventoryManager(loader=self.loader,
                                          sources=['/etc/ansible/hosts'])

        # 管理变量的类,包括主机,组,扩展等变量,之前版本是在 inventory中的
        self.variable_manager = VariableManager(loader=self.loader,
                                                inventory=self.inventory)
        # self.variable_manager.extra_vars = {"host_list": self.host_list}
        self.variable_manager.extra_vars = self.ext_vars

        # print(self.variable_manager.get_vars()) # 所有主机信息

        self.variable_manager.set_inventory(self.inventory)

        # 初始化需要的对象1
        Options = namedtuple('Options', [
            'listtags', 'listtasks', 'listhosts', 'syntax', 'connection',
            'module_path', 'forks', 'private_key_file', 'ssh_common_args',
            'ssh_extra_args', 'sftp_extra_args', 'scp_extra_args', 'become',
            'become_method', 'become_user', 'verbosity', 'check', 'diff'
        ])

        self.options = Options(listtags=False,
                               listtasks=False,
                               listhosts=False,
                               syntax=False,
                               connection='ssh',
                               module_path=None,
                               forks=10,
                               private_key_file=None,
                               ssh_common_args=None,
                               ssh_extra_args=None,
                               sftp_extra_args=None,
                               scp_extra_args=None,
                               become=None,
                               become_method=None,
                               become_user=None,
                               verbosity=None,
                               check=False,
                               diff=False)
        # 初始化需要的对象2

    #定义运行的方法和返回值
    def run(self):
        complex_msg = {}
        if not os.path.exists(self.playbook_path):
            code = 50000
            results = {
                'playbook': self.playbook_path,
                'msg': self.playbook_path + ' playbook is not exist',
                'flag': False
            }

        pbex = PlaybookExecutor(playbooks=[self.playbook_path],
                                inventory=self.inventory,
                                variable_manager=self.variable_manager,
                                loader=self.loader,
                                options=self.options,
                                passwords=self.passwords)
        self.results_callback = mycallback()
        pbex._tqm._stdout_callback = self.results_callback
        try:
            code = pbex.run()
        except AnsibleParserError:
            code = 50000
            results = {
                'playbook': self.playbook_path,
                'msg': self.playbook_path + ' playbook have syntax error',
                'flag': False
            }

            return code, results
        if self.results_callback.status_no_hosts:
            code = 5000
            results = {
                'playbook': self.playbook_path,
                'msg': self.results_callback.status_no_hosts,
                'flag': False,
                'executed': False
            }

            return code, results

    def get_result(self):
        self.result_all = {'success': {}, 'failed': {}, 'unreachable': {}}

        for host, result in self.results_callback.host_ok.items():
            self.result_all['success'][host] = result._result

        for host, result in self.results_callback.host_failed.items():
            self.result_all['failed'][host] = result._result['msg']

        for host, result in self.results_callback.host_unreachable.items():
            self.result_all['unreachable'][host] = result._result['msg']

        # for i in self.result_all['success'].keys():
        #     print('Success Info', i,self.result_all['success'][i])
        # print('Failed Info', self.result_all['failed'])
        # print('Unreachable Info', self.result_all['unreachable'])
        return self.result_all
    Options(
        connection='local',
        module_path='cloud/amazon',
        forks=1, become=None, become_method=None, become_user=None, check=True,
        remote_user=None, private_key_file=None, ssh_common_args=None,
        sftp_extra_args=None, scp_extra_args=None, ssh_extra_args=None,
        verbosity=3, diff=False
    )
)
passwords = dict(vault_pass='')

aws_region = 'us-west-2'

# create inventory and pass to var manager
inventory = InventoryManager(loader=loader)
variable_manager.set_inventory(inventory)


def run(play):
    tqm = None
    results = None
    try:
        tqm = TaskQueueManager(
            inventory=inventory,
            variable_manager=variable_manager,
            loader=loader,
            options=options,
            passwords=passwords,
            stdout_callback='default',
        )
        results = tqm.run(play)
Esempio n. 29
0
                   become_user=None,
                   check=True,
                   remote_user=None,
                   private_key_file=None,
                   ssh_common_args=None,
                   sftp_extra_args=None,
                   scp_extra_args=None,
                   ssh_extra_args=None,
                   verbosity=3))
passwords = dict(vault_pass='')

aws_region = 'us-west-2'

# create inventory and pass to var manager
inventory = InventoryManager(loader=loader)
variable_manager.set_inventory(inventory)


def run(play):
    tqm = None
    results = None
    try:
        tqm = TaskQueueManager(
            inventory=inventory,
            variable_manager=variable_manager,
            loader=loader,
            options=options,
            passwords=passwords,
            stdout_callback='default',
        )
        results = tqm.run(play)
Esempio n. 30
0
class PlaybookRunner(object):
    """
    The plabybook API.
    """
    def __init__(
            self,
            hosts=None,  # a list or dynamic-hosts,
            # default is /etc/ansible/hosts
        playbook_path=None,  # * a playbook file
            forks=C.DEFAULT_FORKS,
            listtags=False,
            listtasks=False,
            listhosts=False,
            syntax=False,
            module_path=None,
            remote_user='******',
            timeout=C.DEFAULT_TIMEOUT,
            ssh_common_args=None,
            ssh_extra_args=None,
            sftp_extra_args=None,
            scp_extra_args=None,
            become=True,
            become_method=None,
            become_user="******",
            verbosity=None,
            extra_vars=None,
            connection_type="ssh",
            passwords=None,
            private_key_file=None,
            check=False):

        C.RETRY_FILES_ENABLED = False
        self.callbackmodule = CallbackModule()
        if playbook_path is None or not os.path.exists(playbook_path):
            raise AnsibleError("Not Found the playbook file: %s." %
                               playbook_path)
        self.playbook_path = playbook_path
        self.inventory = MyInventory(host_list=hosts)
        self.loader = DataLoader()
        self.variable_manager = VariableManager(self.loader, self.inventory)
        self.passwords = passwords or {}

        self.options = Options(listtags=listtags,
                               listtasks=listtasks,
                               listhosts=listhosts,
                               syntax=syntax,
                               timeout=timeout,
                               connection=connection_type,
                               module_path=module_path,
                               forks=forks,
                               remote_user=remote_user,
                               private_key_file=private_key_file,
                               ssh_common_args=ssh_common_args or "",
                               ssh_extra_args=ssh_extra_args or "",
                               sftp_extra_args=sftp_extra_args,
                               scp_extra_args=scp_extra_args,
                               become=become,
                               become_method=become_method,
                               become_user=become_user,
                               verbosity=verbosity,
                               extra_vars=extra_vars or [],
                               check=check,
                               diff=False)

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

        self.variable_manager.set_inventory(self.inventory)
        self.runner = PlaybookExecutor(playbooks=[self.playbook_path],
                                       inventory=self.inventory,
                                       variable_manager=self.variable_manager,
                                       loader=self.loader,
                                       options=self.options,
                                       passwords=self.passwords)
        if self.runner._tqm:
            self.runner._tqm._stdout_callback = self.callbackmodule

    def run(self):
        if not self.inventory.list_hosts("all"):
            raise AnsibleError("Inventory is empty.")

        self.runner.run()
        return self.callbackmodule.output