Example #1
0
class PlayBook(object):
    def __init__(self, inventory='/etc/ansible/hosts', extra_vars=None, private_key_file=None):
        """
        :param playbook: playbook.yml
        :param inventory: inventory file or script
        :type param extra_vars: dict
        :param private_key_file: ssh private key
        """
        self.pbex = None
        self.options = Options(private_key_file=private_key_file, connection='smart', forks=10, timeout=10,
                               verbosity=0, check=False,
                               listtasks=False, listhosts=False, syntax=False,
                               subset=None, module_path=None, become=None, become_user=None, become_method='sudo')

        # initialize needed objects
        self.loader = DataLoader()
        self.variable_manager = VariableManager()
        self.variable_manager.extra_vars = extra_vars
        self.variable_manager.options_vars = {'ansible_check_mode': self.options.check}
        self.inventory = Inventory(loader=self.loader, variable_manager=self.variable_manager, host_list=inventory)
        self.variable_manager.set_inventory(self.inventory)
        # Limits inventory results to a subset of inventory that matches a given pattern
        self.inventory._subset = self.options.subset

    def run_playbook(self, playbook):
        self.pbex = PlaybookExecutor(playbooks=[playbook], inventory=self.inventory,
                                     variable_manager=self.variable_manager,
                                     loader=self.loader, options=self.options,
                                     passwords={'conn_pass': None, 'become_pass': None})
        self.pbex._tqm._stdout_callback = ResultCallback()
        return self.pbex.run()

    def run_play(self, play):
        pass
Example #2
0
 def playbook_api(self,yml_fp):
     loader = DataLoader()
     variable_manager = VariableManager()
     
     inventory = Inventory(
         loader=loader,
         variable_manager=variable_manager,
         host_list=self.ansible_host_list
     )
     
     variable_manager.set_inventory(inventory)
     
     playbooks = ["%s" % yml_fp]
     
     pbex = PlaybookExecutor(
                   playbooks=playbooks,
                   inventory=inventory,
                   variable_manager=variable_manager,
                   loader=loader,
                   options=self.options,
                   passwords=self.passwords
             )
                   
     callback = AnsiCallBack()
     pbex._tqm._stdout_callback = callback
     pbex.run()
     
     return self.evaluate_results(callback)
Example #3
0
def pbexe(sid,war,mode):
  variable_manager = VariableManager()
  loader = DataLoader()

#  inventory = Inventory(loader=loader, variable_manager=variable_manager, host_list=[])
  inventory = Inventory(loader=loader, variable_manager=variable_manager)
  playbook_path = '/etc/ansible/yml/'+sid+'.yml'

  if not os.path.exists(playbook_path):
    print playbook_path
    print '[INFO] The playbook does not exist'
    sys.exit()

  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'])
  options = Options(listtags=False, listtasks=False, listhosts=False, syntax=False, connection='ssh', module_path=None, 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=True, become_method=None, become_user='******', verbosity=None, check=False)

  variable_manager.extra_vars = {'war': war,'mode': mode} # This can accomodate various other command line arguments.`

  passwords = {}

  #cb = ResultCallback()
#  cb = default.CallbackModule()
  pbex = PlaybookExecutor(playbooks=[playbook_path],  inventory=inventory, variable_manager=variable_manager, loader=loader, options=options, passwords=passwords)
#  pbex._tqm._stdout_callback = cb
  op=sys.stdout

  filename='/var/log/ansible/'+time.strftime('%Y%m%d%H%M%S')+'.log'
  opf=open(filename,'w')
  sys.stdout=opf
  results = pbex.run()
  sys.stdout=op
  opf.close
  print open(filename,'r').read()
  return filename
Example #4
0
def pbexe(userid,serial,host,module,apppath,yaml,url=None):
    variable_manager = VariableManager()
    loader = DataLoader()
    hostfile = '/ansible/hosts'
    inventory = Inventory(loader=loader, variable_manager=variable_manager,host_list='/ansible/hosts')
    playbook_path = yaml

    if not os.path.exists(playbook_path):
        print playbook_path
        print '[INFO] The playbook does not exist'
        sys.exit()

    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'])
    options = Options(listtags=False, listtasks=False, listhosts=False, syntax=False, connection='ssh', module_path=None, 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=True, become_method=None, become_user='******', verbosity=None, check=False)

    variable_manager.extra_vars = {
            'host': host,
            'module': module,
            'tomcat_root': apppath,
            'url': url
} # This can accomodate various other command line arguments.`
    passwords = {}
    cb = CallbackModule(serial)
#  cb = default.CallbackModule()
    pbex = PlaybookExecutor( playbooks=[playbook_path],  inventory=inventory, variable_manager=variable_manager, loader=loader, options=options, passwords=passwords)
    pbex._tqm._stdout_callback = cb
    results = pbex.run()
    return results
Example #5
0
def AnsibleTask(task_list,host_list,user):
    '''ansible python api 2.0'''
    loader = DataLoader()
    variable_manager = VariableManager()
    inventory = Inventory(loader=loader, variable_manager=variable_manager, host_list=host_list)
    variable_manager.set_inventory(inventory)
    task_dict = []
    for i in task_list:
        task_dict.append({"action": {"module": i[0], "args": i[1] }})
    variable_manager.extra_vars = {"ansible_ssh_user": user, "ansible_ssh_pass": ""}
    play_source = {"name" : "Ansible PlayBook Run", "hosts": host_list[0], "gather_facts": "no","tasks": task_dict}
    play = Play().load(play_source, variable_manager=variable_manager, loader=loader)
    tqm = None
    try:
        tqm = TaskQueueManager(
            inventory = inventory,
            variable_manager = variable_manager,
            loader = loader,
            options = options,
            passwords = None,
            stdout_callback = 'minimal',
            run_tree = False,
        )
        result = tqm.run(play)
    except Exception,e:
        result = e
Example #6
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():

            variable_manager = VariableManager()
            loader = DataLoader()
            options = self._get_options()
            passwords = {'become_pass': self.sudo_password}

            inventory = Inventory(loader=loader, variable_manager=variable_manager, host_list="localhost")
            variable_manager.set_inventory(inventory)
            playbooks = [self.task_file]

            executor = PlaybookExecutor(
                playbooks=playbooks,
                inventory=inventory,
                variable_manager=variable_manager,
                loader=loader,
                options=options,
                passwords=passwords)

            executor.run()
Example #7
0
def call_ansible(yaml_file, become=False, tag=None):
  """Call Ansible with a playbook."""

  variable_manager = VariableManager()
  loader           = DataLoader()
  inventory        = Inventory(loader, variable_manager)
  variable_manager.set_inventory(inventory)

  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',
                        'tags'])

  options = Options(listtags=False,
                    listtasks=False,
                    listhosts=False,
                    syntax=False,
                    connection='',
                    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=become,
                    become_method='sudo',
                    become_user='******',
                    verbosity=2,
                    check=False,
                    tags=tag)

  pbex = PlaybookExecutor(playbooks=[yaml_file],
                          inventory=inventory,
                          variable_manager=variable_manager,
                          loader=loader,
                          options=options,
                          passwords={})

  logger.debug("Calling Ansible with yaml file: {}".format(yaml_file))
  result = pbex.run()
  if result:
    logger.error("An error occured whilst executing the Ansible Playbook.")
    def test_manager_extra_vars(self):
        extra_vars = dict(a=1, b=2, c=3)
        v = VariableManager()
        v.set_extra_vars(extra_vars)

        self.assertEqual(v.get_vars(), extra_vars)
        self.assertIsNot(v.extra_vars, extra_vars)
Example #9
0
def ansible_task(playbooks):
    Options = namedtuple('Options', \
    ['connection', 'module_path', 'forks', 'become', 'become_method', 'become_user', 'check', 'listhosts', 'listtasks', 'listtags', 'syntax'])

    options = Options(
        connection = 'ssh', 
        module_path = '/opt/ansible/modules',
        forks = 100, 
        become = True, 
        become_method = 'sudo', 
        become_user = '******', 
        check = False, 
        listhosts = None,
        listtasks = None,
        listtags = None,
        syntax = None
    )

    loader = DataLoader()
    variable_manager = VariableManager()
    inventory = Inventory(loader=loader, variable_manager=variable_manager, host_list='/opt/ansible/inventory')
    variable_manager.set_inventory(inventory)

    pb = PlaybookExecutor(playbooks=[playbooks], inventory=inventory, variable_manager=variable_manager, loader=loader, options=options, passwords=None)
    pb.run()

    stats = pb._tqm._stats
    ips = stats.processed.keys()
    return [ {ip : stats.summarize(ip)} for ip in ips ]
Example #10
0
  def execute_action(self, action, args):
    """
    Execute the requested operation
    """
    C.DEFAULT_ROLES_PATH = [os.path.join(ROLESDIR, str(action))]

    i3xfce.loggers.ROOTLOGGER.debug("Executing the %s action", action)
    # Get the real user behind the sudo
    username = os.getenv("SUDO_USER")

    if username is None:
      i3xfce.loggers.ROOTLOGGER.debug("Unable to get SUDO_USER environment variable. This means i3-xfce has not been \
      started using sudo")
      raise Exception("This program must be ran using sudo ")

    i3xfce.loggers.ROOTLOGGER.debug("Creating the option tuple")
    options_tuple = namedtuple('Options', ['connection', 'forks', 'module_path', 'become_user', 'become',
                                           'become_method', 'check', 'verbosity'])
    try:
      # initialize needed objects
      variable_manager = VariableManager()
      variable_manager.extra_vars = dict(action=str(action),
                                         remote_user=username)

      loader = DataLoader()
      i3xfce.loggers.ROOTLOGGER.debug("Creating option to count number of tasks to execute")
      options = options_tuple(connection=None, module_path=None, forks=1, become_user=None,
                              become=None, become_method=None, verbosity=0, check=True)
      tasks_count_callback = TaskCountCallback()
      # create inventory and pass to var manager
      inventory = Inventory(loader=loader, variable_manager=variable_manager, host_list=None)
      variable_manager.set_inventory(inventory)
      # create play with tasks
      play_source = dict(
          name="Ansible Play",
          hosts='localhost',
          gather_facts='no',
          ignore_errors="yes",
          roles=args.parts
          )
      CmdLine._execute_play(play_source, inventory, variable_manager, loader, options, tasks_count_callback)

      i3xfce.loggers.ROOTLOGGER.debug("%i tasks are going to be executed", tasks_count_callback.get_total_tasks_num())
      play_source["ignore_errors"] = "no"
      options = options_tuple(connection=None, module_path=None, forks=1, become_user=None, become=None,
                              become_method=None, verbosity=0, check=args.dryrun)
      self._results_callback = PlaybookExecutionCallback(tasks_count_callback.get_total_tasks_num(),
                                                         tasks_count_callback.get_task_name_max_len())
      CmdLine._execute_play(play_source, inventory, variable_manager, loader, options, self._results_callback)

      self._results_callback.get_progress_bar().stop()
      self._results_callback.get_progress_bar().join()

      if self._results_callback.get_task_failed() is True:
        raise TaskExecutionException("")
    except TaskExecutionException as exc:
      raise
    except Exception as exc:
      raise TaskExecutionException(str(exc))
    def test_manager_play_vars(self):
        mock_play = MagicMock()
        mock_play.get_vars.return_value = dict(foo="bar")
        mock_play.get_roles.return_value = []
        mock_play.get_vars_files.return_value = []

        v = VariableManager()
        self.assertEqual(v.get_vars(play=mock_play), dict(foo="bar"))
Example #12
0
class Runner(object):
    def __init__(self, playbook, display, hosts=None, options={}, passwords={}, vault_pass=None):

        self.options = Options()
        for k, v in options.iteritems():
            setattr(self.options, k, v)

        self.display = display
        self.display.verbosity = self.options.verbosity
        # executor has its own verbosity setting
        playbook_executor.verbosity = self.options.verbosity

        # gets data from YAML/JSON files
        self.loader = DataLoader()
        if vault_pass is not None:
            self.loader.set_vault_password(vault_pass)
        elif 'VAULT_PASS' in os.environ:
            self.loader.set_vault_password(os.environ['VAULT_PASS'])

        # all the variables from all the various places
        self.variable_manager = VariableManager()
        if self.options.python_interpreter is not None:
            self.variable_manager.extra_vars = {
                'ansible_python_interpreter': self.options.python_interpreter
            }

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

        if len(self.inventory.list_hosts()) == 0:
            self.display.error("Provided hosts list is empty.")
            sys.exit(1)

        self.inventory.subset(self.options.subset)

        if len(self.inventory.list_hosts()) == 0:
            self.display.error("Specified limit does not match any hosts.")
            sys.exit(1)

        self.variable_manager.set_inventory(self.inventory)

        # 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):
        # run playbook and get stats
        self.pbex.run()
        stats = self.pbex._tqm._stats

        return stats
Example #13
0
    def test_variable_manager_task_vars(self):
        fake_loader = DictDataLoader({})

        mock_task = MagicMock()
        mock_task._role = None
        mock_task.get_vars.return_value = dict(foo="bar")

        v = VariableManager()
        self.assertEqual(v.get_vars(loader=fake_loader, task=mock_task, use_cache=False).get("foo"), "bar")
Example #14
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'])
Example #15
0
def get_inventory(inventory='hosts'):
    if HAS_ANSIBLE2:
        loader = DataLoader()
        variable_manager = VariableManager()
        inventory = Inventory(loader=loader, variable_manager=variable_manager)
        variable_manager.set_inventory(inventory)
    else:
        inventory_filename = "%s/%s" % (ANSIBLE_DIR, inventory)
        inventory = Inventory(host_list=inventory_filename)
    return inventory
Example #16
0
    def test_variable_manager_play_vars(self):
        fake_loader = DictDataLoader({})

        mock_play = MagicMock()
        mock_play.get_vars.return_value = dict(foo="bar")
        mock_play.get_roles.return_value = []
        mock_play.get_vars_files.return_value = []

        v = VariableManager()
        self.assertEqual(v.get_vars(loader=fake_loader, play=mock_play, use_cache=False).get("foo"), "bar")
Example #17
0
def main(args):
    # Options definition
    # Custom tuple to store playbook options
    Options = namedtuple('Options', ['connection', 'module_path', 'forks',
                                     'become', 'become_method', 'become_user',
                                     'check'])

    # Object initialization
    variable_manager = VariableManager()
    loader = DataLoader()
    options = Options(connection='ssh',module_path='library',
                      forks=100, become=None, become_method=None,
                      become_user=None, check=False)
    passwords = {}

    # Dinamyc inventory
    inventory = Inventory(loader=loader, variable_manager=variable_manager,
                          host_list=args)

    # Inventory assignation
    variable_manager.set_inventory(inventory)

    # Play creation with tasks
    play_source = dict(
         name="Ansible Play",
         hosts=args,
         gather_facts='no',
         tasks=[
             dict(action=dict(module='shell', args='hostname -f'),
                  register='shell_out'),
             dict(action=dict(module='debug',
                              args=dict(msg='{{shell_out.stdout}}')))
         ]
    )

    play = Play().load(play_source, variable_manager=variable_manager,
                       loader=loader)

    # Running it
    tqm = None
    try:
        tqm = TaskQueueManager(
                      inventory=inventory,
                      variable_manager=variable_manager,
                      loader=loader,
                      options=options,
                      passwords=passwords,
                      stdout_callback='default'
        )
        result = tqm.run(play)
    finally:
        if tqm is not None:
                    tqm.cleanup()
    def test_basic_manager(self):
        fake_loader = DictDataLoader({})

        v = VariableManager()
        vars = v.get_vars(loader=fake_loader, use_cache=False)

        #FIXME: not sure why we remove all and only test playbook_dir
        for remove in ['omit', 'vars', 'ansible_version', 'ansible_check_mode', 'ansible_playbook_python']:
            if remove in vars:
                del vars[remove]

        self.assertEqual(vars, dict(playbook_dir='.'))
    def test_variable_manager_role_vars_dependencies(self):
        '''
        Tests vars from role dependencies with duplicate dependencies.
        '''

        v = VariableManager()
        v._fact_cache = defaultdict(dict)

        fake_loader = DictDataLoader({
            # role common-role
            '/etc/ansible/roles/common-role/tasks/main.yml': """
            - debug: msg="{{role_var}}"
            """,
            # We do not need allow_duplicates: yes for this role
            # because eliminating duplicates is done by the execution
            # strategy, which we do not test here.

            # role role1
            '/etc/ansible/roles/role1/vars/main.yml': """
            role_var: "role_var_from_role1"
            """,
            '/etc/ansible/roles/role1/meta/main.yml': """
            dependencies:
              - { role: common-role }
            """,

            # role role2
            '/etc/ansible/roles/role2/vars/main.yml': """
            role_var: "role_var_from_role2"
            """,
            '/etc/ansible/roles/role2/meta/main.yml': """
            dependencies:
              - { role: common-role }
            """,
        })

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

        # The task defined by common-role exists twice because role1
        # and role2 depend on common-role.  Check that the tasks see
        # different values of role_var.
        blocks = play1.compile()
        task = blocks[1].block[0]
        res = v.get_vars(loader=fake_loader, play=play1, task=task)
        self.assertEqual(res['role_var'], 'role_var_from_role1')

        task = blocks[2].block[0]
        res = v.get_vars(loader=fake_loader, play=play1, task=task)
        self.assertEqual(res['role_var'], 'role_var_from_role2')
    def test_basic_manager(self):
        fake_loader = DictDataLoader({})

        v = VariableManager()
        vars = v.get_vars(loader=fake_loader, use_cache=False)
        if 'omit' in vars:
            del vars['omit']
        if 'vars' in vars:
            del vars['vars']
        if 'ansible_version' in vars:
            del vars['ansible_version']

        self.assertEqual(vars, dict(playbook_dir='.'))
Example #21
0
    def test_variable_manager_extra_vars(self):
        fake_loader = DictDataLoader({})

        extra_vars = dict(a=1, b=2, c=3)
        v = VariableManager()
        v.extra_vars = extra_vars

        vars = v.get_vars(loader=fake_loader, use_cache=False)

        for (key, val) in extra_vars.iteritems():
            self.assertEqual(vars.get(key), val)

        self.assertIsNot(v.extra_vars, extra_vars)
Example #22
0
class Runner(object):

    def __init__(self, hostnames, playbook, private_key_file, run_data, become_pass=None,
                 verbosity=0, callback=None, subset_pattern=None):

        self.hostnames = hostnames

        self.playbook = os.path.join(playbooks_dir, playbook)
        self.run_data = run_data

        self.options = Options(subset=subset_pattern, private_key_file=private_key_file, verbosity=verbosity)

        self.display = Display()
        self.display.verbosity = verbosity
        playbook_executor.verbosity = verbosity

        passwords = {'become_pass': None}

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

        self.variable_manager = VariableManager()
        self.variable_manager.extra_vars = self.run_data

        self.inventory = Inventory(loader=self.loader, variable_manager=self.variable_manager, host_list=self.hostnames)
        self.variable_manager.set_inventory(self.inventory)

        self.pbex = playbook_executor.PlaybookExecutor(
            playbooks=[self.playbook],
            inventory=self.inventory,
            variable_manager=self.variable_manager,
            loader=self.loader,
            options=self.options,
            passwords=passwords)

        if callback:
            self.pbex._tqm._stdout_callback = callback

    def run(self):
        self.pbex.run()
        stats = self.pbex._tqm._stats

        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

        return run_success
Example #23
0
def main(argv=sys.argv[1:]):
    #
    # initialize needed objects
    #
    variable_manager = VariableManager()
    loader = DataLoader()
    # https://pymotw.com/2/collections/namedtuple.html
    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'])

    options = Options(listtags=False, listtasks=False, listhosts=False,
                      syntax=False, connection='local', module_path=None,
                      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=True, become_method=None,
                      become_user='******', verbosity=None, check=False)

    passwords = {}

    inventory = Inventory(loader=loader, variable_manager=variable_manager,
                          host_list='./ls_hosts')

    variable_manager.set_inventory(inventory)

    playbook_path = './ls.yml'
    if not os.path.exists(playbook_path):
        print '[INFO] The playbook does not exist'
        sys.exit()

    # This can accomodate various other command line arguments.`
    # variable_manager.extra_vars = {'hosts': 'mywebserver'}

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

    # cb = ResultAccumulator()
    # pbex._tqm._stdout_callback = cb

    results = pbex.run()
    if results != 0:
        print "ERROR"
Example #24
0
def main(argv=sys.argv[1:]):
    Options = namedtuple('Options', ['connection', 'module_path', 'forks',
                                     'become', 'become_method', 'become_user',
                                     'check'])
    # initialize needed objects
    variable_manager = VariableManager()
    loader = DataLoader()
    options = Options(connection='local', module_path='/path/to/mymodules',
                      forks=100, become=None, become_method=None,
                      become_user=None,
                      check=False)

    passwords = dict(vault_pass='******')

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

    variable_manager.set_inventory(inventory)

    # create play with tasks
    play_source = dict(name="Ansible Play",
                       hosts='localhost',
                       gather_facts='no',
                       tasks=[
                           dict(action=dict(module='shell',
                                args='uname -a'), register='shell_out'),
                           dict(action=dict(module='debug',
                                args=dict(msg='{{shell_out.stdout}}')))
                       ]
                       )

    play = Play().load(play_source, variable_manager=variable_manager,
                       loader=loader)

    # actually run it
    tqm = None
    try:
        tqm = TaskQueueManager(inventory=inventory,
                               variable_manager=variable_manager,
                               loader=loader,
                               options=options,
                               passwords=passwords,
                               stdout_callback='default',
                               )

        result = tqm.run(play)
        print result
    finally:
        if tqm is not None:
            tqm.cleanup()
    def test_manager_play_vars_files(self):
        fake_loader = DictDataLoader({
            "/path/to/somefile.yml": """
               foo: bar
            """
        })

        mock_play = MagicMock()
        mock_play.get_vars.return_value = dict()
        mock_play.get_roles.return_value = []
        mock_play.get_vars_files.return_value = ['/path/to/somefile.yml']

        v = VariableManager(loader=fake_loader)
        self.assertEqual(v.get_vars(play=mock_play), dict(foo="bar"))
    def test_variable_manager_play_vars_files(self):
        fake_loader = DictDataLoader({
            "/path/to/somefile.yml": """
               foo: bar
            """
        })

        mock_play = MagicMock()
        mock_play.get_vars.return_value = dict()
        mock_play.get_roles.return_value = []
        mock_play.get_vars_files.return_value = ['/path/to/somefile.yml']

        v = VariableManager()
        self.assertEqual(v.get_vars(loader=fake_loader, play=mock_play, use_cache=False).get("foo"), "bar")
Example #27
0
class AnsibleTask(object):

    def __init__(self, hosts='127.0.0.1', module='shell', args='ls -l',
                 options=DEFAULT_OPTIONS, name='Ansible Play'):
        self.hosts = hosts
        self.module = module
        self.args = args
        self.options = options
        self.name = name
        self.task = dict(action=dict(
            module=self.module, args=self.args
        ), register='shell_out')
        self.tasks = [self.task]
        # initialize needed objects
        self.variable_manager = VariableManager()
        self.loader = DataLoader()
        self.passwords = dict()
        self.inventory = Inventory(loader=self.loader, variable_manager=self.variable_manager, host_list=[self.hosts])
        self.variable_manager.set_inventory(self.inventory)
        self.play_source = dict(
            name=self.name, hosts=self.hosts,
            gather_facts='no', tasks=self.tasks
        )
        self.play = Play().load(self.play_source, loader=self.loader,
                                variable_manager=self.variable_manager)
        self.results_callback = ResultCallback()
        self.return_results = {}
        setattr(self.results_callback, 'task_obj', self)

    def ansible_play(self):
        # run it
        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.results_callback,
                # stdout_callback='default',
            )
            result = tqm.run(self.play)
        finally:
            if tqm is not None:
                tqm.cleanup()
                #self.inventory.clear_pattern_cache()
            if result != 0:
                raise ValueError('SSH Command Failed, resturn: %s' % result)
            return self.return_results
    def test_variable_manager_host_vars_file(self):
        fake_loader = DictDataLoader({
            "host_vars/hostname1.yml": """
               foo: bar
            """,
            "other_path/host_vars/hostname1.yml": """
               foo: bam
               baa: bat
            """,
            "host_vars/host.name.yml": """
               host_with_dots: true
            """,
        })

        v = VariableManager()
        v.add_host_vars_file("host_vars/hostname1.yml", loader=fake_loader)
        v.add_host_vars_file("other_path/host_vars/hostname1.yml", loader=fake_loader)
        self.assertIn("hostname1", v._host_vars_files)
        self.assertEqual(v._host_vars_files["hostname1"], [dict(foo="bar"), dict(foo="bam", baa="bat")])

        mock_host = MagicMock()
        mock_host.get_name.return_value = "hostname1"
        mock_host.get_vars.return_value = dict()
        mock_host.get_groups.return_value = ()
        mock_host.get_group_vars.return_value = dict()

        self.assertEqual(v.get_vars(loader=fake_loader, host=mock_host, use_cache=False).get("foo"), "bam")
        self.assertEqual(v.get_vars(loader=fake_loader, host=mock_host, use_cache=False).get("baa"), "bat")

        v.add_host_vars_file("host_vars/host.name", loader=fake_loader)
        self.assertEqual(v._host_vars_files["host.name"], [dict(host_with_dots=True)])
    def test_base(self):
        test_inv_dir = 'test/inventory'
        for inv in os.listdir(test_inv_dir):
            print "Processing ", inv
            res = dynlxc.main(os.path.join(test_inv_dir, inv), '')

            variable_manager = VariableManager()
            loader = DataLoader()
            self.mock_rv.communicate.return_value = [
                json.dumps(res), 'mocked_err']
            try:
                inventory = Inventory(
                    loader=loader,
                    variable_manager=variable_manager,
                    host_list='inventory/dynlxc.py'
                )
            except Exception as err:
                raise Exception("Inventory file {0} processing result '{1}' "
                                "failed with {2}".format(inv, res, err))
            variable_manager.set_inventory(inventory)

            play_source = dict(name="Ansible Play", hosts='localhost',
                               gather_facts='no')

            playbook = os.path.abspath(os.path.join(test_inv_dir,
                                       '../playbooks', inv))
            if os.path.isfile(playbook):
                with open(playbook) as fh:
                    real_playbook = yaml.load(fh)[0]
                    play_source.update(real_playbook)

            play = Play().load(play_source, variable_manager=variable_manager,
                               loader=loader)
            tqm = None
            try:
                tqm = TaskQueueManager(
                    inventory=inventory,
                    variable_manager=variable_manager,
                    loader=loader,
                    options=self.options,
                    passwords=None,
                    stdout_callback='default',
                )
                result = tqm.run(play)
                assert result == 0, ("Ansible playbook exitcode "
                                     "different from 0")
            finally:
                if tqm is not None:
                    tqm.cleanup()
Example #30
0
 def __init__(self, hosts='127.0.0.1', module='shell', args='ls -l',
              options=DEFAULT_OPTIONS, name='Ansible Play'):
     self.hosts = hosts
     self.module = module
     self.args = args
     self.options = options
     self.name = name
     self.task = dict(action=dict(
         module=self.module, args=self.args
     ), register='shell_out')
     self.tasks = [self.task]
     # initialize needed objects
     self.variable_manager = VariableManager()
     self.loader = DataLoader()
     self.passwords = dict()
     self.inventory = Inventory(loader=self.loader, variable_manager=self.variable_manager, host_list=[self.hosts])
     self.variable_manager.set_inventory(self.inventory)
     self.play_source = dict(
         name=self.name, hosts=self.hosts,
         gather_facts='no', tasks=self.tasks
     )
     self.play = Play().load(self.play_source, loader=self.loader,
                             variable_manager=self.variable_manager)
     self.results_callback = ResultCallback()
     self.return_results = {}
     setattr(self.results_callback, 'task_obj', self)
Example #31
0
    def __init__(self,
                 exec_mode,
                 work_name,
                 username,
                 options_dict,
                 describe,
                 mongoclient=None):
        '''
        ansible的基类,为adhoc、playbook等父类
        :parm:
            exec_mode:ansible工作类型,接受adhoc、palybook等
            work_name:该任务的名称,用于日志
            username:执行者
            options_dict:该任务的特定设置
            mongoclient:初始化mongo连接类
        '''

        self.logger = logging.getLogger("ansible")
        if exec_mode in ('adhoc', 'playbook'):
            self.exec_mode = exec_mode
        else:
            self.logger.warn(
                '正在准备执行ansible任务,准备工作失败,原因:参数exec_mode必须是adhoc或者是playbook')
            return (False, '参数exec_mode必须是adhoc或者是playbook')

        if isinstance(work_name, str) and work_name:
            self.work_name = work_name
        else:
            self.logger.warn('正在准备执行ansible任务,准备工作失败,原因:参数work_name必须是非字符串')
            return (False, '参数work_name必须是非字符串')

        if isinstance(username, str) and username:
            self.username = username
        else:
            self.logger.warn('正在准备执行ansible任务,准备工作失败,原因:参数username必须是非字符串')
            return (False, '参数username必须是非字符串')

        if isinstance(options_dict, dict) and options_dict:
            self.options_dict = options_dict
        else:
            self.logger.warn('正在准备执行ansible任务,准备工作失败,原因:参数options_dict必须是非空字典')
            return (False, '参数options_dict必须是非空字典')

        if mongoclient is None:
            self.mongoclient = Op_Mongo()
        else:
            self.mongoclient = mongoclient

        self.work_uuid = str(uuid.uuid4())
        self.log_router = Routing_Logging()
        self.describe = describe

        if exec_mode == 'adhoc':
            self.log_prefix = '正在执行用户' + username + '的名为' + work_name + 'uuid为' + self.work_uuid + '的ansible临时任务,'
        else:
            self.log_prefix = '正在执行用户' + username + '的名为' + work_name + 'uuid为' + self.work_uuid + '的ansible-playbook任务,'

        # 下面是加载和初始化相关类
        self._parse_options()
        self.passwords = {
            'conn_pass': self.options.ask_pass,
            'become_pass': self.options.become_ask_pass
        }
        # 设置passwords
        self.inventory_file = self.options_dict.get('inventory', '')

        self.loader = DataLoader()
        self._get_vault_pwd()
        self.variable_manager = VariableManager()
        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.inventory = Inventory(loader=self.loader,
                                   variable_manager=self.variable_manager,
                                   host_list=self.inventory_file)
        self.variable_manager.set_inventory(self.inventory)
        self.inventory.subset(self.options.subset)
Example #32
0
class Base():
    def __init__(self,
                 exec_mode,
                 work_name,
                 username,
                 options_dict,
                 describe,
                 mongoclient=None):
        '''
        ansible的基类,为adhoc、playbook等父类
        :parm:
            exec_mode:ansible工作类型,接受adhoc、palybook等
            work_name:该任务的名称,用于日志
            username:执行者
            options_dict:该任务的特定设置
            mongoclient:初始化mongo连接类
        '''

        self.logger = logging.getLogger("ansible")
        if exec_mode in ('adhoc', 'playbook'):
            self.exec_mode = exec_mode
        else:
            self.logger.warn(
                '正在准备执行ansible任务,准备工作失败,原因:参数exec_mode必须是adhoc或者是playbook')
            return (False, '参数exec_mode必须是adhoc或者是playbook')

        if isinstance(work_name, str) and work_name:
            self.work_name = work_name
        else:
            self.logger.warn('正在准备执行ansible任务,准备工作失败,原因:参数work_name必须是非字符串')
            return (False, '参数work_name必须是非字符串')

        if isinstance(username, str) and username:
            self.username = username
        else:
            self.logger.warn('正在准备执行ansible任务,准备工作失败,原因:参数username必须是非字符串')
            return (False, '参数username必须是非字符串')

        if isinstance(options_dict, dict) and options_dict:
            self.options_dict = options_dict
        else:
            self.logger.warn('正在准备执行ansible任务,准备工作失败,原因:参数options_dict必须是非空字典')
            return (False, '参数options_dict必须是非空字典')

        if mongoclient is None:
            self.mongoclient = Op_Mongo()
        else:
            self.mongoclient = mongoclient

        self.work_uuid = str(uuid.uuid4())
        self.log_router = Routing_Logging()
        self.describe = describe

        if exec_mode == 'adhoc':
            self.log_prefix = '正在执行用户' + username + '的名为' + work_name + 'uuid为' + self.work_uuid + '的ansible临时任务,'
        else:
            self.log_prefix = '正在执行用户' + username + '的名为' + work_name + 'uuid为' + self.work_uuid + '的ansible-playbook任务,'

        # 下面是加载和初始化相关类
        self._parse_options()
        self.passwords = {
            'conn_pass': self.options.ask_pass,
            'become_pass': self.options.become_ask_pass
        }
        # 设置passwords
        self.inventory_file = self.options_dict.get('inventory', '')

        self.loader = DataLoader()
        self._get_vault_pwd()
        self.variable_manager = VariableManager()
        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.inventory = Inventory(loader=self.loader,
                                   variable_manager=self.variable_manager,
                                   host_list=self.inventory_file)
        self.variable_manager.set_inventory(self.inventory)
        self.inventory.subset(self.options.subset)

    def _get_vault_pwd(self):
        '''
        获取vault密码,并初始化vault密码
        '''

        vault_pwd_file = self.options_dict.get('vault_password_file', False)
        ask_vault_pass = self.options_dict.get('ask_vault_pass', False)

        if ask_vault_pass:
            vault_password = ask_vault_pass
        else:
            if vault_pwd_file:
                this_path = os.path.realpath(
                    os.path.expanduser(vault_pwd_file))
                if os.path.exists(this_path):
                    mode = self.loader.is_executable(this_path)
                    result = read_file(this_path,
                                       mode=mode,
                                       sprfmt=b'\r\n',
                                       outfmt='bytes')
                    if result[0]:
                        vault_password = result[1]
                    else:
                        vault_password = None
                else:
                    vault_password = None
            else:
                vault_password = None

        if vault_password:
            b_vault_password = string2bytes(vault_password)
            self.loader.set_vault_password(b_vault_password)
            self.vault_password = vault_password
        else:
            self.vault_password = None

    def _parse_options(self):
        '''
        获取options字典
        '''

        keys_list = []
        values_list = []
        for key, value in self.options_dict.items():
            keys_list.append(key)
            values_list.append(value)

        Options = namedtuple('Options', keys_list)
        self.options = Options._make(values_list)

    def _show_protectfield(self):
        protectfield_list = [
            'ask_pass',
            'ask_su_pass',
            'ask_sudo_pass',
            'ask_vault_pass',
            'become_ask_pass',
            'new_vault_password_file',
            'vault_password_file',
            'private_key_file',
        ]

        log_options = {}
        for field in self.options_dict:
            if field in protectfield_list:
                log_options[field] = '***hidden***'
            else:
                log_options[field] = self.options_dict[field]

        return log_options
Example #33
0
class YoRunner(object):
    Options = namedtuple("Options", [
        'connection',
        'module_path',
        'private_key_file',
        "remote_user",
        'timeout',
        'forks',
        'become',
        'become_method',
        'become_user',
        'check',
        'extra_vars',
    ])

    def __init__(
            self,
            hosts=C.DEFAULT_HOST_LIST,
            forks=C.DEFAULT_FORKS,  # 5
            timeout=C.DEFAULT_TIMEOUT,  # SSH timeout = 10s
            remote_user=C.DEFAULT_REMOTE_USER,  # root
            module_path=None,  # dirs of custome modules
            connection_type="smart",
            become=None,
            become_method=None,
            become_user=None,
            check=False,
            passwords=None,
            extra_vars=None,
            private_key_file=None,
            gather_facts='no'):
        self.pattern = ''
        self.variable_manager = VariableManager()
        self.loader = DataLoader()
        self.gather_facts = gather_facts
        self.options = self.Options(
            connection=connection_type,
            timeout=timeout,
            module_path=module_path,
            forks=forks,
            become=become,
            become_method=become_method,
            become_user=become_user,
            check=check,
            remote_user=remote_user,
            extra_vars=extra_vars or [],
            private_key_file=private_key_file,
        )
        # self.variable_manager.extra_vars = load_extra_vars(self.loader,
        #                                                    options=self.options)
        self.variable_manager.extra_vars = extra_vars
        self.variable_manager.options_vars = load_options_vars(self.options)
        self.passwords = passwords or {}
        self.inventory = YoInventory(hosts)
        self.variable_manager.set_inventory(self.inventory)
        self.tasks = []
        self.play_source = None
        self.play = None
        self.runner = None
        self.timestamp = str(time.time())
        self.filename = FILENAME % (self.timestamp, '')
        self.have_script = 0

    def set_callback(self, callback):
        self.results_callback = callback

    @staticmethod
    def check_module_args(module_name, module_args=''):
        if module_name in C.MODULE_REQUIRE_ARGS and not module_args:
            err = "No argument passed to '%s' module." % module_name
            print(err)
            return False
        return True

    def task_add(self, task_tuple):
        for task in task_tuple:
            if not self.check_module_args(task.module, task.args):
                return
            if task.module == u'script':
                self.have_script = 1
                script = Script.objects.filter(id=task.args)
                if os.path.exists(self.filename):
                    os.remove(self.filename)
                script_name = FILENAME % (self.timestamp,
                                          '-' + str(script.get().id))
                output = open(script_name, 'w')
                output.writelines(script.get().formatScript())
                output.close()
            if self.have_script == 1:
                self.tasks.append(
                    dict(action=dict(
                        module=task.module,
                        args=script_name,
                    )))
            else:
                self.tasks.append(
                    dict(action=dict(
                        module=task.module,
                        args=task.args,
                    )))

    def run(
        self,
        task_tuple,
    ):  # pattern='all'):
        """
        :param task_tuple:  (('shell', 'ls'), ('ping', ''))
        :param pattern:
        :param timestamp:
        :return:
        """
        self.task_add(task_tuple)

        self.play_source = dict(name=self.timestamp,
                                hosts='all',
                                gather_facts=self.gather_facts,
                                tasks=self.tasks)

        self.play = Play().load(
            self.play_source,
            variable_manager=self.variable_manager,
            loader=self.loader,
        )

        self.runner = TaskQueueManager(
            inventory=self.inventory,
            variable_manager=self.variable_manager,
            loader=self.loader,
            options=self.options,
            passwords=self.passwords,
            stdout_callback=self.results_callback,
        )

        # if not self.inventory.list_hosts("all"):
        #     raise AnsibleError("Inventory is empty.")
        #
        # if not self.inventory.list_hosts(self.pattern):
        #     raise AnsibleError(
        #         "pattern: %s  dose not match any hosts." % self.pattern)

        try:
            self.runner.run(self.play)
        finally:
            if self.runner:
                self.runner.cleanup()
            if self.loader:
                self.loader.cleanup_all_tmp_files()
            if self.have_script:
                self.cleanup_script()

    def cleanup_script(self):
        # if os.path.exists(self.filename):
        #     os.remove(self.filename)
        # return self.filename
        for name in glob.glob(self.filename + '*'):
            if os.path.exists(name):
                print(name)
                os.remove(name)
Example #34
0
  def __init__(self,playbooks,host_list,remote_user='******',passwords='null',group_name='all',ask_pass=False,forks=5,ext_vars=None):
    self.playbooks = playbooks
    self.host_list = host_list
    self.remote_user  = remote_user
    self.passwords = dict(conn_pass=passwords)
    self.group_name = group_name
    self.ask_pass  = ask_pass
    self.forks     = forks
    self.connection='smart'
    self.ext_vars  = ext_vars

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

    # 管理变量的类,包括主机,组,扩展等变量,之前版本是在 inventory中的
    self.variable_manager = VariableManager()

    # 根据inventory加载对应变量
    self.inventory = Inventory(loader=self.loader, 
                               variable_manager=self.variable_manager,
                               group_name=self.group_name,  # 项目名对应组名,区分当前执行的内容
                               ext_vars=self.ext_vars,
                               host_list=self.host_list)

    self.variable_manager.set_inventory(self.inventory)

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

    # 初始化需要的对象2
    self.options = self.Options(connection=self.connection, 
                                remote_user=self.remote_user,
                                ask_pass=self.ask_pass,
                                sudo_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
                               )

    # 初始化console输出
    self.callback = ExtendCallback()
Example #35
0
    def run(self, command, *args):
        self._check_ansible()

        if HAS_ANSIBLE_1:
            import ansible.inventory
            import ansible.runner
            command = self.get_command(command, *args)
            kwargs = {}
            if self.ansible_inventory is not None:
                kwargs["host_list"] = self.ansible_inventory
            out = ansible.runner.Runner(pattern=self.host,
                                        module_name="shell",
                                        module_args=command,
                                        **kwargs).run()["contacted"][self.host]

            # Ansible return an unicode object but this is bytes ...
            # A simple test case is:
            # >>> assert File("/bin/true").content == open("/bin/true").read()
            stdout_bytes = b"".join((chr(ord(c)) for c in out['stdout']))
            stderr_bytes = b"".join((chr(ord(c)) for c in out['stderr']))

            result = base.CommandResult(
                self,
                out['rc'],
                stdout_bytes,
                stderr_bytes,
                command,
                stdout=out["stdout"],
                stderr=out["stderr"],
            )
            logger.info("RUN %s", result)

            return result

        if HAS_ANSIBLE_2:
            from collections import namedtuple
            from ansible.parsing.dataloader import DataLoader
            from ansible.vars import VariableManager
            from ansible.inventory import Inventory
            from ansible.playbook.play import Play
            from ansible.executor.task_queue_manager import TaskQueueManager
            from ansible.plugins.callback import CallbackBase

            class SilentCallbackModule(CallbackBase):
                """ A callback module that does not print anything, but keeps tabs
                on what's happening in an Ansible play.
                """
                def __init__(self):
                    self.unreachable = {}
                    self.contacted = {}

                def runner_on_ok(self, host, result):
                    self.contacted[host] = {'success': True, 'result': result}

                def runner_on_failed(self, host, result, ignore_errors=False):
                    self.contacted[host] = {'success': False, 'result': result}

                def runner_on_unreachable(self, host, result):
                    self.unreachable[host] = result

            callback = SilentCallbackModule()
            command = self.get_command(command, *args)
            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=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=None,
                              become_method=None,
                              become_user=None,
                              verbosity=None,
                              check=False)
            passwords = dict()

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

            # create play with tasks
            play_source = dict(
                name="Ansible Play",
                hosts=self.host,
                gather_facts='no',
                tasks=[dict(action=dict(module="shell", args=command))])
            play = Play().load(play_source,
                               variable_manager=variable_manager,
                               loader=loader)

            # actually run it
            tqm = None
            try:
                tqm = TaskQueueManager(
                    inventory=inventory,
                    variable_manager=variable_manager,
                    loader=loader,
                    options=options,
                    passwords=passwords,
                    stdout_callback=callback,
                )
                tqm.run(play)

                ret = base.CommandResult(
                    self,
                    0 if callback.contacted[self.host][u'success'] else 1,
                    bytes(callback.contacted[self.host][u'result']
                          ["stdout_lines"]),
                    b"",
                    command,
                    stdout=callback.contacted[self.host][u'result']["stdout"],
                    stderr=callback.contacted[self.host][u'result']["stdout"],
                )

                return ret
            finally:
                if tqm is not None:
                    tqm.cleanup()
Example #36
0
def apply_playbook(playbook_path,
                   hosts_inv,
                   host_user,
                   ssh_priv_key_file_path,
                   variables=None,
                   proxy_setting=None):
    """
    Executes an Ansible playbook to the given host
    :param playbook_path: the (relative) path to the Ansible playbook
    :param hosts_inv: a list of hostnames/ip addresses to which to apply the Ansible playbook
    :param host_user: A user for the host instances (must be a password-less sudo user if playbook has "sudo: yes"
    :param ssh_priv_key_file_path: the file location of the ssh key
    :param variables: a dictionary containing any substitution variables needed by the Jinga 2 templates
    :param proxy_setting: string containing host:port of the proxy server in use
    :return: the results
    """
    if not os.path.isfile(playbook_path):
        raise Exception('Requested playbook not found - ' + playbook_path)
    if not os.path.isfile(ssh_priv_key_file_path):
        raise Exception('Requested private SSH key not found - ' +
                        ssh_priv_key_file_path)

    import ansible.constants
    ansible.constants.HOST_KEY_CHECKING = False

    variable_manager = VariableManager()
    if variables:
        variable_manager.extra_vars = variables

    loader = DataLoader()
    inventory = Inventory(loader=loader,
                          variable_manager=variable_manager,
                          host_list=hosts_inv)
    variable_manager.set_inventory(inventory)
    loader = DataLoader()

    ssh_common_args = None
    ssh_extra_args = None
    ssh_connection = 'ssh'
    proxy_command = None
    if proxy_setting:
        tokens = re.split(':', proxy_setting)
        # TODO - Need to configure the proxy settings to avoid adding entries into the host's ~/.ssh/config file

    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', 'host_key_checking', 'transport', 'proxy_command'
    ])
    ansible_opts = options(listtags=False,
                           listtasks=False,
                           listhosts=False,
                           syntax=False,
                           connection=ssh_connection,
                           module_path=None,
                           forks=100,
                           remote_user=host_user,
                           private_key_file=ssh_priv_key_file_path,
                           ssh_common_args=ssh_common_args,
                           ssh_extra_args=ssh_extra_args,
                           sftp_extra_args=None,
                           scp_extra_args=None,
                           become=None,
                           become_method=None,
                           become_user='******',
                           verbosity=1111,
                           check=False,
                           host_key_checking=True,
                           transport='paramiko',
                           proxy_command=proxy_command)
    logger.debug('Setting up Ansible Playbook Executor')
    executor = PlaybookExecutor(playbooks=[playbook_path],
                                inventory=inventory,
                                variable_manager=variable_manager,
                                loader=loader,
                                options=ansible_opts,
                                passwords=None)

    logger.debug('Executing Ansible Playbook - ' + playbook_path)
    retval = executor.run()

    if retval != 0:
        logger.error('Playbook application failed [' + playbook_path +
                     '] with return value of - ' + str(retval))
        raise Exception('Playbook not applied - ' + playbook_path)

    return retval
Example #37
0
    def test_variable_manager_precedence(self, mock_basedir):
        '''
        Tests complex variations and combinations of get_vars() with different
        objects to modify the context under which variables are merged.
        '''

        v = VariableManager()
        v._fact_cache = defaultdict(dict)

        fake_loader = DictDataLoader({
            # inventory1
            '/etc/ansible/inventory1':
            """
            [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
            """,

            # 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"
            """,
        })

        mock_basedir.return_value = './'
        inv1 = Inventory(loader=fake_loader,
                         variable_manager=v,
                         host_list='/etc/ansible/inventory1')
        inv1.set_playbook_basedir('./')

        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(loader=fake_loader, 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(loader=fake_loader, play=play1, task=task)
        self.assertEqual(res['default_var'], 'default_var_from_defaults_only1')

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

        res = v.get_vars(loader=fake_loader, 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
        """)

        v.add_group_vars_file("/etc/ansible/group_vars/all",
                              loader=fake_loader)
        v.add_group_vars_file("/etc/ansible/group_vars/group1",
                              loader=fake_loader)
        v.add_group_vars_file("/etc/ansible/group_vars/group2",
                              loader=fake_loader)
        v.add_host_vars_file("/etc/ansible/host_vars/host1",
                             loader=fake_loader)

        res = v.get_vars(loader=fake_loader, 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['host_var'], 'host_var_from_host_vars_host1')

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

        res = v.get_vars(loader=fake_loader, play=play1, host=h1)
        self.assertEqual(res['fact_cache_var'],
                         'fact_cache_var_from_fact_cache')
Example #38
0
    def run(self):

        super(PlaybookCLI, self).run()

        # Note: slightly wrong, this is written so that implicit localhost
        # Manage passwords
        sshpass = None
        becomepass = None
        vault_pass = None
        passwords = {}

        # initial error check, to make sure all specified playbooks are accessible
        # before we start running anything through the playbook executor
        for playbook in self.args:
            if not os.path.exists(playbook):
                raise AnsibleError("the playbook: %s could not be found" %
                                   playbook)
            if not (os.path.isfile(playbook)
                    or stat.S_ISFIFO(os.stat(playbook).st_mode)):
                raise AnsibleError(
                    "the playbook: %s does not appear to be a file" % playbook)

        # don't deal with privilege escalation or passwords when we don't need to
        if not self.options.listhosts and not self.options.listtasks and not self.options.listtags and not self.options.syntax:
            self.normalize_become_options()
            (sshpass, becomepass) = self.ask_passwords()
            passwords = {'conn_pass': sshpass, 'become_pass': becomepass}

        loader = DataLoader()

        if self.options.vault_password_file:
            # read vault_pass from a file
            vault_pass = CLI.read_vault_password_file(
                self.options.vault_password_file, loader=loader)
            loader.set_vault_password(vault_pass)
        elif self.options.ask_vault_pass:
            vault_pass = self.ask_vault_passwords()
            loader.set_vault_password(vault_pass)

        # create the variable manager, which will be shared throughout
        # the code, ensuring a consistent view of global variables
        variable_manager = VariableManager()
        variable_manager.extra_vars = load_extra_vars(loader=loader,
                                                      options=self.options)

        variable_manager.options_vars = load_options_vars(self.options)

        # create the inventory, and filter it based on the subset specified (if any)
        inventory = Inventory(loader=loader,
                              variable_manager=variable_manager,
                              host_list=self.options.inventory)
        variable_manager.set_inventory(inventory)

        # (which is not returned in list_hosts()) is taken into account for
        # warning if inventory is empty.  But it can't be taken into account for
        # checking if limit doesn't match any hosts.  Instead we don't worry about
        # limit if only implicit localhost was in inventory to start with.
        #
        # Fix this when we rewrite inventory by making localhost a real host (and thus show up in list_hosts())
        no_hosts = False
        if len(inventory.list_hosts()) == 0:
            # Empty inventory
            display.warning(
                "provided hosts list is empty, only localhost is available")
            no_hosts = True
        inventory.subset(self.options.subset)
        if len(inventory.list_hosts()) == 0 and no_hosts is False:
            # Invalid limit
            raise AnsibleError("Specified --limit does not match any hosts")

        # flush fact cache if requested
        if self.options.flush_cache:
            self._flush_cache(inventory, variable_manager)

        # create the playbook executor, which manages running the plays via a task queue manager
        pbex = PlaybookExecutor(playbooks=self.args,
                                inventory=inventory,
                                variable_manager=variable_manager,
                                loader=loader,
                                options=self.options,
                                passwords=passwords)

        results = pbex.run()

        if isinstance(results, list):
            for p in results:

                display.display('\nplaybook: %s' % p['playbook'])
                for idx, play in enumerate(p['plays']):
                    if play._included_path is not None:
                        loader.set_basedir(play._included_path)
                    else:
                        pb_dir = os.path.realpath(
                            os.path.dirname(p['playbook']))
                        loader.set_basedir(pb_dir)

                    msg = "\n  play #%d (%s): %s" % (idx + 1, ','.join(
                        play.hosts), play.name)
                    mytags = set(play.tags)
                    msg += '\tTAGS: [%s]' % (','.join(mytags))

                    if self.options.listhosts:
                        playhosts = set(inventory.get_hosts(play.hosts))
                        msg += "\n    pattern: %s\n    hosts (%d):" % (
                            play.hosts, len(playhosts))
                        for host in playhosts:
                            msg += "\n      %s" % host

                    display.display(msg)

                    all_tags = set()
                    if self.options.listtags or self.options.listtasks:
                        taskmsg = ''
                        if self.options.listtasks:
                            taskmsg = '    tasks:\n'

                        def _process_block(b):
                            taskmsg = ''
                            for task in b.block:
                                if isinstance(task, Block):
                                    taskmsg += _process_block(task)
                                else:
                                    if task.action == 'meta':
                                        continue

                                    all_tags.update(task.tags)
                                    if self.options.listtasks:
                                        cur_tags = list(
                                            mytags.union(set(task.tags)))
                                        cur_tags.sort()
                                        if task.name:
                                            taskmsg += "      %s" % task.get_name(
                                            )
                                        else:
                                            taskmsg += "      %s" % task.action
                                        taskmsg += "\tTAGS: [%s]\n" % ', '.join(
                                            cur_tags)

                            return taskmsg

                        all_vars = variable_manager.get_vars(loader=loader,
                                                             play=play)
                        play_context = PlayContext(play=play,
                                                   options=self.options)
                        for block in play.compile():
                            block = block.filter_tagged_tasks(
                                play_context, all_vars)
                            if not block.has_tasks():
                                continue
                            taskmsg += _process_block(block)

                        if self.options.listtags:
                            cur_tags = list(mytags.union(all_tags))
                            cur_tags.sort()
                            taskmsg += "      TASK TAGS: [%s]\n" % ', '.join(
                                cur_tags)

                        display.display(taskmsg)

            return 0
        else:
            return results
Example #39
0
class ANSRunner(object):
    """ 
    This is a General object for parallel execute modules. 
    """
    def __init__(self, resource, redisKey=None, logId=None, *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(kwargs)
        self.results_raw = {}
        self.redisKey = redisKey
        self.logId = logId

    def __initializeData(self, kwargs):
        """ 初始化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'
        ])

        self.variable_manager = VariableManager()
        self.loader = DataLoader()
        self.options = Options(
            connection='smart',
            module_path=None,
            forks=100,
            timeout=10,
            remote_user=kwargs.get('remote_user', 'root'),
            ask_pass=False,
            private_key_file=None,
            ssh_common_args=None,
            ssh_extra_args=None,
            sftp_extra_args=None,
            scp_extra_args=None,
            become=True,
            become_method=kwargs.get('become_method', 'sudo'),
            become_user=kwargs.get('become_user', 'root'),
            verbosity=kwargs.get('verbosity', None),
            check=False,
            listhosts=False,
            listtasks=False,
            listtags=False,
            syntax=False,
            ask_value_pass=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_model(self, host_list, module_name, module_args):
        """ 
        run module from andible ad-hoc. 
        module_name: ansible module_name 
        module_args: ansible module args 
        """
        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)
        tqm = None
        if self.redisKey or self.logId:
            self.callback = ModelResultsCollectorToSave(
                self.redisKey, self.logId)
        else:
            self.callback = ModelResultsCollector()
        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
            constants.HOST_KEY_CHECKING = False  #关闭第一次使用ansible连接客户端是输入命令
            tqm.run(play)
        except Exception as err:
            logger.error(msg="run model failed: {err}".format(err=str(err)))
            if self.redisKey:
                DsRedis.OpsAnsibleModel.lpush(self.redisKey, data=err)
            if self.logId: AnsibleSaveResult.Model.insert(self.logId, err)
        finally:
            if tqm is not None:
                tqm.cleanup()

    def run_playbook(self, host_list, playbook_path, extra_vars=dict()):
        """ 
        run ansible palybook 
        """
        try:
            if self.redisKey or self.logId:
                self.callback = PlayBookResultsCollectorToSave(
                    self.redisKey, self.logId)
            else:
                self.callback = PlayBookResultsCollector()
            extra_vars['host'] = ','.join(host_list)
            self.variable_manager.extra_vars = extra_vars
            executor = PlaybookExecutor(
                playbooks=[playbook_path],
                inventory=self.inventory,
                variable_manager=self.variable_manager,
                loader=self.loader,
                options=self.options,
                passwords=self.passwords,
            )
            executor._tqm._stdout_callback = self.callback
            constants.HOST_KEY_CHECKING = False  #关闭第一次使用ansible连接客户端是输入命令
            constants.DEPRECATION_WARNINGS = False
            constants.RETRY_FILES_ENABLED = False
            executor.run()
        except Exception as err:
            logger.error(msg="run playbook failed: {err}".format(err=str(err)))
            if self.redisKey:
                DsRedis.OpsAnsibleModel.lpush(self.redisKey, data=err)
            if self.logId: AnsibleSaveResult.Model.insert(self.logId, err)
            return False

    def get_model_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

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

        return json.dumps(self.results_raw)

    def get_playbook_result(self):
        self.results_raw = {
            'skipped': {},
            'failed': {},
            'ok': {},
            "status": {},
            'unreachable': {},
            "changed": {}
        }

        for host, result in self.callback.task_ok.items():
            self.results_raw['ok'][host] = result

        for host, result in self.callback.task_failed.items():
            self.results_raw['failed'][host] = result

        for host, result in self.callback.task_status.items():
            self.results_raw['status'][host] = result

        for host, result in self.callback.task_changed.items():
            self.results_raw['changed'][host] = result

        for host, result in self.callback.task_skipped.items():
            self.results_raw['skipped'][host] = result

        for host, result in self.callback.task_unreachable.items():
            self.results_raw['unreachable'][host] = result
        return self.results_raw

    def handle_cmdb_data(self, data):
        '''处理setup返回结果方法'''
        data_list = []
        for k, v in json.loads(data).items():
            if k == "success":
                for x, y in v.items():
                    cmdb_data = {}
                    data = y.get('ansible_facts')
                    disk_size = 0
                    cpu = data['ansible_processor'][-1]
                    for k, v in data['ansible_devices'].items():
                        if k[0:2] in ['sd', 'hd', 'ss', 'vd']:
                            disk = int(
                                (int(v.get('sectors')) *
                                 int(v.get('sectorsize'))) / 1024 / 1024)
                            disk_size = disk_size + disk
                    cmdb_data['serial'] = data['ansible_product_serial'].split(
                    )[0]
                    cmdb_data['ip'] = x
                    cmdb_data['cpu'] = cpu.replace('@', '')
                    cmdb_data['ram_total'] = int(data['ansible_memtotal_mb'])
                    cmdb_data['disk_total'] = int(disk_size)
                    cmdb_data[
                        'system'] = data['ansible_distribution'] + ' ' + data[
                            'ansible_distribution_version'] + ' ' + data[
                                'ansible_userspace_bits']
                    cmdb_data['model'] = data['ansible_product_name'].split(
                        ':')[0]
                    cmdb_data['cpu_number'] = data['ansible_processor_count']
                    cmdb_data['vcpu_number'] = data['ansible_processor_vcpus']
                    cmdb_data['cpu_core'] = data['ansible_processor_cores']
                    cmdb_data['hostname'] = data['ansible_hostname']
                    cmdb_data['kernel'] = str(data['ansible_kernel'])
                    cmdb_data['manufacturer'] = data['ansible_system_vendor']
                    if data['ansible_selinux']:
                        cmdb_data['selinux'] = data['ansible_selinux'].get(
                            'status')
                    else:
                        cmdb_data['selinux'] = 'disabled'
                    cmdb_data['swap'] = int(data['ansible_swaptotal_mb'])
                    #获取网卡资源
                    nks = []
                    for nk in data.keys():
                        if re.match(r"^ansible_(eth|bind|eno|ens|em)\d+?", nk):
                            device = data.get(nk).get('device')
                            try:
                                address = data.get(nk).get('ipv4').get(
                                    'address')
                            except:
                                address = 'unkown'
                            macaddress = data.get(nk).get('macaddress')
                            module = data.get(nk).get('module')
                            mtu = data.get(nk).get('mtu')
                            if data.get(nk).get('active'): active = 1
                            else: active = 0
                            nks.append({
                                "device": device,
                                "address": address,
                                "macaddress": macaddress,
                                "module": module,
                                "mtu": mtu,
                                "active": active
                            })
                    cmdb_data['status'] = 0
                    cmdb_data['nks'] = nks
                    data_list.append(cmdb_data)
            elif k == "unreachable":
                for x, y in v.items():
                    cmdb_data = {}
                    cmdb_data['status'] = 1
                    cmdb_data['ip'] = x
                    data_list.append(cmdb_data)
        if data_list:
            return data_list
        else:
            return False

    def handle_cmdb_crawHw_data(self, data):
        data_list = []
        for k, v in json.loads(data).items():
            if k == "success":
                for x, y in v.items():
                    cmdb_data = {}
                    cmdb_data['ip'] = x
                    data = y.get('ansible_facts')
                    cmdb_data['mem_info'] = data.get(
                        'ansible_mem_detailed_info')
                    cmdb_data['disk_info'] = data.get(
                        'ansible_disk_detailed_info')
                    data_list.append(cmdb_data)
        if data_list:
            return data_list
        else:
            return False

    def handle_model_data(self, data, module_name, module_args=None):
        '''处理ANSIBLE 模块输出内容'''
        module_data = json.loads(data)
        failed = module_data.get('failed')
        success = module_data.get('success')
        unreachable = module_data.get('unreachable')
        data_list = []
        if module_name == "raw":
            if failed:
                for x, y in failed.items():
                    data = {}
                    data['ip'] = x
                    try:
                        data['msg'] = y.get('stdout').replace(
                            '\t\t',
                            '<br>').replace('\r\n',
                                            '<br>').replace('\t', '<br>')
                    except:
                        data['msg'] = None
                    if y.get('rc') == 0:
                        data['status'] = 'succeed'
                    else:
                        data['status'] = 'failed'
                    data_list.append(data)
            elif success:
                for x, y in success.items():
                    data = {}
                    data['ip'] = x
                    try:
                        data['msg'] = y.get('stdout').replace(
                            '\t\t',
                            '<br>').replace('\r\n',
                                            '<br>').replace('\t', '<br>')
                    except:
                        data['msg'] = None
                    if y.get('rc') == 0:
                        data['status'] = 'succeed'
                    else:
                        data['status'] = 'failed'
                    data_list.append(data)

        elif module_name == "ping":
            if success:
                for x, y in success.items():
                    data = {}
                    data['ip'] = x
                    if y.get('ping'):
                        data['msg'] = y.get('ping')
                        data['status'] = 'succeed'
                    data_list.append(data)
        else:
            if success:
                for x, y in success.items():
                    data = {}
                    data['ip'] = x
                    if y.get('invocation'):
                        data['msg'] = "Ansible %s with %s execute success." % (
                            module_name, module_args)
                        data['status'] = 'succeed'
                    data_list.append(data)

            elif failed:
                for x, y in failed.items():
                    data = {}
                    data['ip'] = x
                    data['msg'] = y.get('msg')
                    data['status'] = 'failed'
                    data_list.append(data)

        if unreachable:
            for x, y in unreachable.items():
                data = {}
                data['ip'] = x
                data['msg'] = y.get('msg')
                data['status'] = 'failed'
                data_list.append(data)
        if data_list:
            return data_list
        else:
            return False
Example #40
0
    def exec_ansible_api(self, playbooks_file):
        variable_manager = VariableManager()
        loader = DataLoader()

        ds = loader.load_from_file(playbooks_file)
        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'
        ])
        options = Options(connection='ssh',
                          module_path=None,
                          forks=100,
                          remote_user='******',
                          private_key_file='id_rsa',
                          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)

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

        # Currently we are limiting to one playbook
        play_source = ds[0]
        play = Play().load(play_source,
                           variable_manager=variable_manager,
                           loader=loader)

        tqm = None
        try:
            tqm = TaskQueueManager(inventory=inventory,
                                   variable_manager=variable_manager,
                                   loader=loader,
                                   options=options,
                                   passwords=None,
                                   stdout_callback=Global.display)
            result = tqm.run(play)
            # Exit gdeploy in case of errors and user has explicitly set
            # not to ignore errors
            if result != 0 and Global.ignore_errors != 'yes':
                msg = "Error while executing playbook %s, exiting"\
                      %playbooks_file
                print msg
                Global.logger.error(msg)
                self.cleanup_and_quit(1)
            elif result != 0 and Global.ignore_errors == 'yes':
                msg = "Error while executing playbook %s, ignoring errors..."\
                      %playbooks_file
                Global.logger.error(msg)
                print msg
        except AnsibleError, e:
            print "%s" % e
Example #41
0
    def __init__(self, playbook, become_pass, verbosity=0):

        self.options = Options()
        self.options.verbosity = verbosity

        self.display = Display()
        self.display.verbosity = self.options.verbosity
        playbook_executor.verbosity = self.options.verbosity

        passwords = {'become_pass': become_pass}

        self.loader = DataLoader()
        self.loader.set_vault_password(os.environ['VAULT_PASS'])

        self.variable_manager = VariableManager()
        self.variable_manager.extra_vars = self.run_data




Options = namedtuple('Options', ['connection', 'module_path', 'forks', 'become', 'become_method', 'become_user', 'check'])
# initialize needed objects
variable_manager = VariableManager()
loader = DataLoader()
options = Options(connection='local', module_path='/path/to/mymodules', forks=100, become=None, become_method=None, become_user=None, check=False)
passwords = dict(vault_pass='******')

# Instantiate our ResultCallback for handling results as they come in
results_callback = ResultCallback()
                  metavar="MULTIINSTANCE_URL")


(options, args) = parser.parse_args()

checkRequiredArguments(options, parser)

# read instance data
instance_file = options.instance_file
with open(instance_file, 'r') as fh:
    instance_data = json.load(fh)

Options = namedtuple('Options',
                     ['connection', 'module_path', 'forks', 'become', 'become_method', 'become_user', 'check'])
# initialize needed objects
variable_manager = VariableManager()

instance_number = instance_data['number']
variables = {'openslides_secure_key': random_string(50),
             'openslides_instance_db_password': random_string(12),
             'openslides_instance_systemd_port': str(23232 + instance_number * 2),
             'openslides_instance_port': str(23232 + (instance_number * 2 + 1)),
             'postgres_host': 'localhost',
             'postgres_user': '******',
             'postgres_password': options.postgres_password,
             'upload_dir': options.upload_dir,
             'openslides_instance_file': instance_file,
             'openslides_multiinstance_api_url': options.multiinstance_url}

for instance_var in instance_data.keys():
    variables['openslides_instance_' + instance_var] = instance_data[instance_var]
Example #43
0
    def run_playbook(self,
                     playbook_file,
                     playbook_variables=None,
                     option_overrides=None):
        """
        Run a playbook from file with the variables provided.

        :param playbook_file: the location of the playbook
        :param playbook_variables: extra variables for the playbook
        """
        # on the first run, the playbook that initializes the
        # inventory will not have yet run, so we should ensure
        # that the directory for it exists, at the least, so
        # ansible doesn't complain
        if not exists(self.host_list):
            makedirs(self.host_list)

        variable_manager = VariableManager()
        data_loader = DataLoader()
        inventory = Inventory(
            loader=data_loader,
            variable_manager=variable_manager,
            host_list=self.host_list,
        )
        variable_manager.set_inventory(inventory)
        variable_manager.extra_vars = playbook_variables

        # until Ansible's display logic is less hack-ey we need
        # to mutate their global in __main__
        options = self.generate_playbook_options(playbook_file)
        display.verbosity = options.verbosity

        # we want to log everything so we can parse output
        # nicely later from files and don't miss output due
        # to the pretty printer, if it's on
        from ..oct import __file__ as root_dir
        callback_loader.add_directory(
            join(dirname(root_dir), 'ansible', 'oct', 'callback_plugins'))
        constants.DEFAULT_CALLBACK_WHITELIST = [
            'log_results', 'generate_junit'
        ]
        environ['ANSIBLE_LOG_ROOT_PATH'] = self.log_directory

        if options.verbosity == 1:
            # if the user has not asked for verbose output
            # we will use our pretty printer for progress
            # on the TTY
            constants.DEFAULT_STDOUT_CALLBACK = 'pretty_progress'

            # we really don't want output in std{err,out}
            # that we didn't put there, but some code in
            # Ansible calls directly to the Display, not
            # through a callback, so we need to ensure
            # that those raw calls don't go to stdout
            display.display = partial(display.display, log_only=True)
        else:
            # if the user asks for verbose output, we want
            # to give them nicer output than the default
            # plugin, anyway
            constants.DEFAULT_STDOUT_CALLBACK = 'default_with_output_lists'

        if option_overrides:
            for key in option_overrides:
                if hasattr(options, key):
                    setattr(options, key, option_overrides[key])

        result = PlaybookExecutor(
            playbooks=[playbook_file],
            inventory=inventory,
            variable_manager=variable_manager,
            loader=data_loader,
            options=options,
            passwords=None,
        ).run()

        if result != TaskQueueManager.RUN_OK:
            # TODO: this seems bad, but can we discover the thread here to join() it?
            sleep(0.2)
            raise ClickException('\nPlaybook execution failed with code ' +
                                 str(result))
Example #44
0
class MyRunner(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
            result = 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 = [BASE_DIR + '/handlers/ansible/v1_0/sudoers.yml']
            logger.info('ymal file path:%s' % filenames)
            template_file = TEMPLATE_DIR
            if not os.path.exists(template_file):
                logger.error('%s 路径不存在 ' % template_file)
                sys.exit()

            extra_vars = {}
            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
            logger.info('playbook 额外参数:%s' % self.variable_manager.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:
            logger.error("run_playbook:%s" % e)

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

        for host, result in self.callback.host_failed.items():
            logger.info('ansible run host_failed :%s' % result._result)
            if 'msg' in result._result:
                self.results_raw['failed'][host] = result._result['msg']
            else:
                self.results_raw['failed'][host] = result._result['stderr']

        for host, result in self.callback.host_unreachable.items():
            logger.info('ansible run host_unreachable :%s' % result._result)
            if 'msg' in result._result:
                self.results_raw['unreachable'][host] = result._result['msg']
            else:
                self.results_raw['unreachable'][host] = result._result[
                    'stderr']

        logger.debug("Ansible执行结果集:%s" % self.results_raw)
        return self.results_raw
Example #45
0
    def run_ansible(self, inv=[]):
        Options = namedtuple('Options', [
            'connection', 'module_path', 'forks', 'become', 'become_method',
            'become_user', 'check'
        ])
        # initialize needed objects
        variable_manager = VariableManager()
        loader = DataLoader()

        options = Options(connection='ssh',
                          module_path='',
                          forks=100,
                          become=False,
                          become_method="sudo",
                          become_user="******",
                          check=False)

        # Instantiate our ResultCallback for handling results as they come in
        results_callback = ResultCallback()

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

        # create play with tasks
        play_source = dict(
            name="Inventory Play",
            hosts='all',
            gather_facts='yes',
            tasks=[
                dict(action=dict(
                    module='shell',
                    args=
                    "/usr/sbin/dmidecode | grep -i 'UUID:' | sed 's/[\t ]*UUID: //gI'"
                ),
                     become=True,
                     register='dmidecode_out'),
            ])
        play = Play().load(play_source,
                           variable_manager=variable_manager,
                           loader=loader)

        # actually run it
        tqm = None
        try:
            tqm = TaskQueueManager(
                inventory=inventory,
                variable_manager=variable_manager,
                loader=loader,
                options=options,
                passwords=None,
                stdout_callback=
                results_callback,  # Use our custom callback instead of the ``default`` callback plugin
            )
            result = tqm.run(play)
        except Exception as e:
            pass
        finally:
            if tqm is not None:
                tqm.cleanup()
        return result
Example #46
0
    def run(self):
        ''' use Runner lib to do SSH things '''

        super(AdHocCLI, self).run()

        # only thing left should be host pattern
        pattern = self.args[0]

        # ignore connection password cause we are local
        if self.options.connection == "local":
            self.options.ask_pass = False

        sshpass = None
        becomepass = None
        vault_pass = None

        self.normalize_become_options()
        (sshpass, becomepass) = self.ask_passwords()
        passwords = {'conn_pass': sshpass, 'become_pass': becomepass}

        if self.options.vault_password_file:
            # read vault_pass from a file
            vault_pass = CLI.read_vault_password_file(
                self.options.vault_password_file)
        elif self.options.ask_vault_pass:
            vault_pass = self.ask_vault_passwords(ask_vault_pass=True,
                                                  ask_new_vault_pass=False,
                                                  confirm_new=False)[0]

        loader = DataLoader(vault_password=vault_pass)
        variable_manager = VariableManager()
        variable_manager.extra_vars = load_extra_vars(loader=loader,
                                                      options=self.options)

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

        hosts = inventory.list_hosts(pattern)
        if len(hosts) == 0:
            self.display.warning(
                "provided hosts list is empty, only localhost is available")

        if self.options.listhosts:
            for host in hosts:
                self.display.display('    %s' % host)
            return 0

        if self.options.module_name in C.MODULE_REQUIRE_ARGS and not self.options.module_args:
            raise AnsibleOptionsError("No argument passed to %s module" %
                                      self.options.module_name)

        #TODO: implement async support
        #if self.options.seconds:
        #    callbacks.display("background launch...\n\n", color='cyan')
        #    results, poller = runner.run_async(self.options.seconds)
        #    results = self.poll_while_needed(poller)
        #else:
        #    results = runner.run()

        # create a pseudo-play to execute the specified module via a single task
        play_ds = self._play_ds(pattern)
        play = Play().load(play_ds,
                           variable_manager=variable_manager,
                           loader=loader)

        if self.options.one_line:
            cb = 'oneline'
        else:
            cb = 'minimal'

        # now create a task queue manager to execute the play
        self._tqm = None
        try:
            self._tqm = TaskQueueManager(
                inventory=inventory,
                variable_manager=variable_manager,
                loader=loader,
                display=self.display,
                options=self.options,
                passwords=passwords,
                stdout_callback=cb,
            )
            result = self._tqm.run(play)
        finally:
            if self._tqm:
                self._tqm.cleanup()

        return result
Example #47
0
    def test_variable_manager_group_vars_file(self):
        fake_loader = DictDataLoader({
            "group_vars/all.yml":
            """
               foo: bar
            """,
            "group_vars/somegroup.yml":
            """
               bam: baz
            """,
            "other_path/group_vars/somegroup.yml":
            """
               baa: bat
            """,
            "group_vars/some.group.yml":
            """
               group_with_dots: true
            """,
        })

        v = VariableManager()
        v.add_group_vars_file("group_vars/all.yml", loader=fake_loader)
        v.add_group_vars_file("group_vars/somegroup.yml", loader=fake_loader)
        v.add_group_vars_file("other_path/group_vars/somegroup.yml",
                              loader=fake_loader)
        self.assertIn("somegroup", v._group_vars_files)
        self.assertEqual(v._group_vars_files["all"], [dict(foo="bar")])
        self.assertEqual(v._group_vars_files["somegroup"],
                         [dict(bam="baz"), dict(baa="bat")])

        mock_group = MagicMock()
        mock_group.name = "somegroup"
        mock_group.get_ancestors.return_value = ()
        mock_group.get_vars.return_value = dict()

        mock_host = MagicMock()
        mock_host.get_name.return_value = "hostname1"
        mock_host.get_vars.return_value = dict()
        mock_host.get_groups.return_value = (mock_group, )
        mock_host.get_group_vars.return_value = dict()

        vars = v.get_vars(loader=fake_loader, host=mock_host, use_cache=False)
        self.assertEqual(vars.get("foo"), "bar")
        self.assertEqual(vars.get("baa"), "bat")

        v.add_group_vars_file("group_vars/some.group", loader=fake_loader)
        self.assertEqual(v._group_vars_files["some.group"],
                         [dict(group_with_dots=True)])
Example #48
0
 def __init__(self, resource, *args, **kwargs):
     self.resource = resource
     self.loader = DataLoader()
     self.variable_manager = VariableManager()
     self.inventory = self._set_inventory(resource)
     self.results_raw = {}
Example #49
0
from ansible.vars import VariableManager
from ansible.inventory import Inventory
from ansible.playbook.play import Play
from ansible.executor.task_queue_manager import TaskQueueManager
from ansible.executor.playbook_executor import PlaybookExecutor

from ansible.plugins import callback_loader
from ansible.plugins.callback import CallbackBase

#import os
#import logging

Options = namedtuple('Options', ['connection', 'module_path', 'forks', 'become', 'become_method', 'become_user', 'check'])
options = Options(connection='smart', module_path=None, forks=10, become=None, become_method=None, become_user=None, check=False)
loader = DataLoader()
variable_manager = VariableManager()
inventory = Inventory(loader=loader, variable_manager=variable_manager)
variable_manager.set_inventory(inventory)

#get result output
class ResultsCollector(CallbackBase):
    def __init__(self, *args, **kwargs):
        super(ResultsCollector, self).__init__(*args, **kwargs)
        self.host_ok = []
        self.host_unreachable = []
        self.host_failed = []

    def v2_runner_on_unreachable(self, result, ignore_errors=False):
        name = result._host.get_name()
        task = result._task.get_name()
        print "ansible unreachable, name:%s, task:%s " % (nova, task)
Example #50
0
    def run(self):

        super(ConsoleCLI, self).run()

        sshpass = None
        becomepass = None
        vault_pass = None

        # hosts
        if len(self.args) != 1:
            self.pattern = 'all'
        else:
            self.pattern = self.args[0]
        self.options.cwd = self.pattern

        # dynamically add modules as commands
        self.modules = self.list_modules()
        for module in self.modules:
            setattr(
                self,
                'do_' + module,
                lambda arg, module=module: self.default(module + ' ' + arg))
            setattr(self,
                    'help_' + module,
                    lambda module=module: self.helpdefault(module))

        self.normalize_become_options()
        (sshpass, becomepass) = self.ask_passwords()
        self.passwords = {'conn_pass': sshpass, 'become_pass': becomepass}

        self.loader = DataLoader()

        if self.options.vault_password_file:
            # read vault_pass from a file
            vault_pass = CLI.read_vault_password_file(
                self.options.vault_password_file, loader=self.loader)
            self.loader.set_vault_password(vault_pass)
        elif self.options.ask_vault_pass:
            vault_pass = self.ask_vault_passwords()[0]
            self.loader.set_vault_password(vault_pass)

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

        if len(self.inventory.list_hosts(self.pattern)) == 0:
            # Empty inventory
            display.warning(
                "provided hosts list is empty, only localhost is available")

        self.inventory.subset(self.options.subset)
        self.groups = self.inventory.list_groups()
        self.hosts = [x.name for x in self.inventory.list_hosts(self.pattern)]

        # This hack is to work around readline issues on a mac:
        #  http://stackoverflow.com/a/7116997/541202
        if 'libedit' in readline.__doc__:
            readline.parse_and_bind("bind ^I rl_complete")
        else:
            readline.parse_and_bind("tab: complete")

        histfile = os.path.join(os.path.expanduser("~"),
                                ".ansible-console_history")
        try:
            readline.read_history_file(histfile)
        except IOError:
            pass

        atexit.register(readline.write_history_file, histfile)
        self.set_prompt()
        self.cmdloop()
Example #51
0
    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)
Example #52
0
class AdHocRunner(object):
    """
    ADHoc接口
    """
    Options = namedtuple("Options", [
        'connection', 'module_path', 'private_key_file', "remote_user",
        'timeout', 'forks', 'become', 'become_method', 'become_user',
        'check', 'extra_vars',
    ]
                         )

    results_callback_class = AdHocResultCallback

    def __init__(self,
                 hosts=c.DEFAULT_HOST_LIST,
                 forks=c.DEFAULT_FORKS,  # 5
                 timeout=c.DEFAULT_TIMEOUT,  # SSH timeout = 10s
                 remote_user=c.DEFAULT_REMOTE_USER,  # root
                 module_path=None,  # dirs of custome modules
                 connection_type="smart",
                 become=None,
                 become_method=None,
                 become_user=None,
                 check=False,
                 passwords=None,
                 extra_vars=None,
                 private_key_file=None,
                 gather_facts='no'):

        self.pattern = ''
        self.variable_manager = VariableManager()
        self.loader = DataLoader()
        self.gather_facts = gather_facts
        self.results_callback = AdHocRunner.results_callback_class()
        self.options = self.Options(
            connection=connection_type,
            timeout=timeout,
            module_path=module_path,
            forks=forks,
            become=become,
            become_method=become_method,
            become_user=become_user,
            check=check,
            remote_user=remote_user,
            extra_vars=extra_vars or [],
            private_key_file=private_key_file,
        )

        self.variable_manager.extra_vars = load_extra_vars(self.loader,
                                                           options=self.options)
        self.variable_manager.options_vars = load_options_vars(self.options)
        self.passwords = passwords or {}
        self.inventory = JMSInventory(hosts)
        self.variable_manager.set_inventory(self.inventory)
        self.tasks = []
        self.play_source = None
        self.play = None
        self.runner = None

    @staticmethod
    def check_module_args(module_name, module_args=''):
        if module_name in c.MODULE_REQUIRE_ARGS and not module_args:
            err = "No argument passed to '%s' module." % module_name
            print(err)
            return False
        return True

    def run(self, task_tuple, pattern='all', task_name='Ansible Ad-hoc'):
        """
        :param task_tuple:  (('shell', 'ls'), ('ping', ''))
        :param pattern:
        :param task_name:
        :return:
        """
        for module, args in task_tuple:
            if not self.check_module_args(module, args):
                return
            self.tasks.append(
                dict(action=dict(
                    module=module,
                    args=args,
                ))
            )

        self.play_source = dict(
            name=task_name,
            hosts=pattern,
            gather_facts=self.gather_facts,
            tasks=self.tasks
        )

        self.play = Play().load(
            self.play_source,
            variable_manager=self.variable_manager,
            loader=self.loader,
        )

        self.runner = TaskQueueManager(
            inventory=self.inventory,
            variable_manager=self.variable_manager,
            loader=self.loader,
            options=self.options,
            passwords=self.passwords,
            stdout_callback=self.results_callback,
        )

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

        if not self.inventory.list_hosts(self.pattern):
            raise AnsibleError(
                "pattern: %s  dose not match any hosts." % self.pattern)

        try:
            self.runner.run(self.play)
        except Exception as e:
            logger.warning(e)
        else:
            # logger.debug(self.results_callback.result_q)
            return self.results_callback.result_q
        finally:
            if self.runner:
                self.runner.cleanup()
            if self.loader:
                self.loader.cleanup_all_tmp_files()

    def clean_result(self):
        """
        :return: {
            "success": ['hostname',],
            "failed": [('hostname', 'msg'), {}],
        }
        """
        result = {'success': [], 'failed': []}
        for host in self.results_callback.result_q['contacted']:
            result['success'].append(host)

        for host, msgs in self.results_callback.result_q['dark'].items():
            msg = '\n'.join(['{} {}: {}'.format(
                msg.get('module_stdout', ''),
                msg.get('invocation', {}).get('module_name'),
                msg.get('msg', '')) for msg in msgs])
            result['failed'].append((host, msg))
        return result
Example #53
0
# Email: [email protected]
#
# this is the Interface package of Ansible2 API
#

import json
from ansible.plugins.callback import CallbackBase
from ansible.parsing.dataloader import DataLoader
from ansible.vars import VariableManager
from ansible.inventory import Inventory
from ansible.playbook.play import Play
from ansible.executor.task_queue_manager import TaskQueueManager
from ansible.executor.playbook_executor import PlaybookExecutor

loader = DataLoader()  # 用来加载解析yaml文件或JSON内容,并且支持vault的解密
variable_manager = VariableManager()  # 管理变量的类,包括主机,组,扩展等变量,之前版本是在 inventory 中的
inventory = Inventory(loader=loader, variable_manager=variable_manager)
variable_manager.set_inventory(inventory)  # 根据 inventory 加载对应变量


class Options(object):
    '''
     这是一个公共的类,因为ad-hoc和playbook都需要一个options参数
     并且所需要拥有不同的属性,但是大部分属性都可以返回None或False
     因此用这样的一个类来省去初始化大一堆的空值的属性
     '''
    def __init__(self):
        self.connection = "local"
        self.forks = 1
        self.check = False
Example #54
0
class PlayBookRunner(object):
    """
    用于执行AnsiblePlaybook的接口.简化Playbook对象的使用.
    """
    Options = namedtuple('Options', [
        'listtags', 'listtasks', 'listhosts', 'syntax', 'connection',
        'module_path', 'forks', 'remote_user', 'private_key_file', 'timeout',
        'ssh_common_args', 'ssh_extra_args', 'sftp_extra_args',
        'scp_extra_args', 'become', 'become_method', 'become_user',
        'verbosity', 'check', 'extra_vars'])

    def __init__(self,
                 hosts=None,
                 playbook_path=None,
                 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 = PlaybookResultCallBack()
        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.loader = DataLoader()
        self.variable_manager = VariableManager()
        self.passwords = passwords or {}
        self.inventory = JMSInventory(hosts)

        self.options = self.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
        )

        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)

        # 初始化playbook的executor
        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()
        self.runner._tqm.cleanup()
        return self.callbackmodule.output
Example #55
0
def launch_ansible_playbook(list_ip, playbook, extra_variable=None):
    """
    Applies an Ansible playbook
    :param list_ip: the ips
    :param playbook: the playboos to be applied
    :param extra_variable: dict of the playbook variables to be applied
    """
    if not os.path.isfile(playbook):
        raise Exception('Requested playbook is not found - ' + playbook)

    if not playbook:
        logger.warn('Unable to find playbook - ' + playbook)

    variable_manager = VariableManager()

    if extra_variable is not None:
        variable_manager.extra_vars = extra_variable
        logger.info(extra_variable)
    else:
        logger.info('NO EXTRA VARS')
    loader = DataLoader()
    inventory = Inventory(loader=loader,
                          variable_manager=variable_manager,
                          host_list=list_ip)
    variable_manager.set_inventory(inventory)

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

    ansible_opts = options(listtags=None,
                           listtasks=None,
                           listhosts=None,
                           syntax=False,
                           connection='ssh',
                           module_path=None,
                           forks=100,
                           remote_user=None,
                           private_key_file=None,
                           ssh_common_args=None,
                           ssh_extra_args=None,
                           become=True,
                           become_method='sudo',
                           become_user=None,
                           verbosity=11111,
                           check=False,
                           sftp_extra_args=None,
                           scp_extra_args=None)

    logger.debug('Setting up Ansible Playbook Executor for playbook - ' +
                 playbook)
    executor = PlaybookExecutor(playbooks=[playbook],
                                inventory=inventory,
                                variable_manager=variable_manager,
                                loader=loader,
                                options=ansible_opts,
                                passwords=None)

    logger.debug('Executing Ansible Playbook - ' + playbook)
    ret = executor.run()
    return ret
Example #56
0
    def __init__(self,
                 hosts=None,
                 playbook_path=None,
                 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 = PlaybookResultCallBack()
        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.loader = DataLoader()
        self.variable_manager = VariableManager()
        self.passwords = passwords or {}
        self.inventory = JMSInventory(hosts)

        self.options = self.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
        )

        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)

        # 初始化playbook的executor
        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
Example #57
0
class AnsibleRunner(object):
    def __init__(self, vault_pass='', connection='local', module_path='',
                forks=100, become=None, become_method=None, become_user=None,
                check=False):
        """
        初始化ansible信息
        """
        Options = namedtuple('Options',
                    ['connection',
                    'module_path',
                    'forks',
                    'become',
                    'become_method',
                    'become_user',
                    'check']
                )
        self.options = Options(connection=connection,
                    module_path=module_path,
                    forks=forks,
                    become=become,
                    become_method=become_method,
                    become_user=become_user,
                    check=check
                )
        self.variable_manager = VariableManager()
        self.loader = DataLoader()
        self.passwords = dict(vault_pass=vault_pass)


    def init_inventory(self, host_list='localhost'):
        # 创建inventory
        # 把inventory传递给variable_manager管理
        self.inventory = Inventory(loader=self.loader,
                    variable_manager=self.variable_manager,
                    host_list=host_list
                )
        self.variable_manager.set_inventory(self.inventory)




    def init_play(self, hosts='localhost', module='ping', args=''):
        #
        # 创建playbook
        #
        # create play with tasks
        #
        self.play_source =  dict(
                name = "Ansible Play",
                hosts = hosts,
                gather_facts = 'no',
                tasks = [
                    dict(action=dict(module=module,
                                    args=args),
                        register='task_out'),
                    dict(action=dict(module='debug',
                                    args=dict(msg='{{task_out.stdout}}')))
                 ]
            )
        self.play = Play().load(self.play_source,
                        variable_manager=self.variable_manager,
                        loader=self.loader
                    )


    def run_it(self):
        #
        # 结果回调类实例化
        #
        # Instantiate our ResultCallback for handling results as they come in
        #
        results_callback = ResultCallback()

        #
        # 通过TaskQueueManager().run()执行ansible,具体语法如下
        # "TaskQueueManager(
        # 指定inventory,loader,variable_manager,
        #   options,passwords, stdout_callback
        # ).run(play)"
        #
        # actually run it
        #
        tqm = None
        try:
            tqm = TaskQueueManager(
                      inventory=self.inventory,
                      variable_manager=self.variable_manager,
                      loader=self.loader,
                      options=self.options,
                      passwords=self.passwords,
                      stdout_callback=results_callback,
                  )
            result = tqm.run(self.play)
        finally:
            if tqm is not None:

                tqm.cleanup()
        return result
Example #58
0
class MyWSRunner(MyRunner):
    """
    This is a General object for parallel execute modules.
    """
    def __init__(self, resource, *args, **kwargs):
        self.resource = resource
        self.loader = DataLoader()
        self.variable_manager = VariableManager()
        self.inventory = self._set_inventory(resource)
        self.results_raw = {}

    def _set_inventory(self, resource):
        # initialize needed objects
        inventory = MyInventory(resource, self.loader,
                                self.variable_manager).inventory
        self.variable_manager.set_inventory(inventory)
        return 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
        """
        self.results_raw = {'success': {}, 'failed': {}, 'unreachable': {}}
        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'
        ])

        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)

        passwords = dict(sshpass=None, becomepass=None)

        # 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
        callback = ResultsCollector()
        try:
            tqm = TaskQueueManager(
                inventory=self.inventory,
                variable_manager=self.variable_manager,
                loader=self.loader,
                options=options,
                passwords=passwords,
            )
            tqm._stdout_callback = callback
            result = tqm.run(play)
        finally:
            if tqm is not None:
                tqm.cleanup()

        for host, result in callback.host_ok.items():
            self.results_raw['success'][host] = result._result.get(
                'stdout') + result._result.get('stderr')

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

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

        logger.info(self.results_raw)
        return self.results_raw
Example #59
0
class ConsoleCLI(CLI, cmd.Cmd):

    modules = []

    def __init__(self, args):

        super(ConsoleCLI, self).__init__(args)

        self.intro = 'Welcome to the ansible console.\nType help or ? to list commands.\n'

        self.groups = []
        self.hosts = []
        self.pattern = None
        self.variable_manager = None
        self.loader = None
        self.passwords = dict()

        self.modules = None
        cmd.Cmd.__init__(self)

    def parse(self):
        self.parser = CLI.base_parser(
            usage='%prog <host-pattern> [options]',
            runas_opts=True,
            inventory_opts=True,
            connect_opts=True,
            check_opts=True,
            vault_opts=True,
            fork_opts=True,
            module_opts=True,
        )

        # options unique to shell
        self.parser.add_option(
            '--step',
            dest='step',
            action='store_true',
            help="one-step-at-a-time: confirm each task before running")

        self.parser.set_defaults(cwd='*')
        self.options, self.args = self.parser.parse_args(self.args[1:])

        display.verbosity = self.options.verbosity
        self.validate_conflicts(runas_opts=True,
                                vault_opts=True,
                                fork_opts=True)

        return True

    def get_names(self):
        return dir(self)

    def cmdloop(self):
        try:
            cmd.Cmd.cmdloop(self)
        except KeyboardInterrupt:
            self.do_exit(self)

    def set_prompt(self):
        login_user = self.options.remote_user or getpass.getuser()
        self.selected = self.inventory.list_hosts(self.options.cwd)
        prompt = "%s@%s (%d)[f:%s]" % (login_user, self.options.cwd,
                                       len(self.selected), self.options.forks)
        if self.options.become and self.options.become_user in [None, 'root']:
            prompt += "# "
            color = C.COLOR_ERROR
        else:
            prompt += "$ "
            color = C.COLOR_HIGHLIGHT
        self.prompt = stringc(prompt, color)

    def list_modules(self):
        modules = set()
        if self.options.module_path is not None:
            for i in self.options.module_path.split(os.pathsep):
                module_loader.add_directory(i)

        module_paths = module_loader._get_paths()
        for path in module_paths:
            if path is not None:
                modules.update(self._find_modules_in_path(path))
        return modules

    def _find_modules_in_path(self, path):

        if os.path.isdir(path):
            for module in os.listdir(path):
                if module.startswith('.'):
                    continue
                elif os.path.isdir(module):
                    self._find_modules_in_path(module)
                elif module.startswith('__'):
                    continue
                elif any(module.endswith(x) for x in C.BLACKLIST_EXTS):
                    continue
                elif module in C.IGNORE_FILES:
                    continue
                elif module.startswith('_'):
                    fullpath = '/'.join([path, module])
                    if os.path.islink(fullpath):  # avoids aliases
                        continue
                    module = module.replace('_', '', 1)

                module = os.path.splitext(module)[0]  # removes the extension
                yield module

    def default(self, arg, forceshell=False):
        """ actually runs modules """
        if arg.startswith("#"):
            return False

        if not self.options.cwd:
            display.error("No host found")
            return False

        if arg.split()[0] in self.modules:
            module = arg.split()[0]
            module_args = ' '.join(arg.split()[1:])
        else:
            module = 'shell'
            module_args = arg

        if forceshell is True:
            module = 'shell'
            module_args = arg

        self.options.module_name = module

        result = None
        try:
            check_raw = self.options.module_name in ('command', 'shell',
                                                     'script', 'raw')
            play_ds = dict(
                name="Ansible Shell",
                hosts=self.options.cwd,
                gather_facts='no',
                tasks=[
                    dict(action=dict(module=module,
                                     args=parse_kv(module_args,
                                                   check_raw=check_raw)))
                ])
            play = Play().load(play_ds,
                               variable_manager=self.variable_manager,
                               loader=self.loader)
        except Exception as e:
            display.error(u"Unable to build command: %s" % to_unicode(e))
            return False

        try:
            cb = 'minimal'  #FIXME: make callbacks configurable
            # now create a task queue manager to execute the play
            self._tqm = None
            try:
                self._tqm = TaskQueueManager(
                    inventory=self.inventory,
                    variable_manager=self.variable_manager,
                    loader=self.loader,
                    options=self.options,
                    passwords=self.passwords,
                    stdout_callback=cb,
                    run_additional_callbacks=C.DEFAULT_LOAD_CALLBACK_PLUGINS,
                    run_tree=False,
                )

                result = self._tqm.run(play)
            finally:
                if self._tqm:
                    self._tqm.cleanup()
                if self.loader:
                    self.loader.cleanup_all_tmp_files()

            if result is None:
                display.error("No hosts found")
                return False
        except KeyboardInterrupt:
            display.error('User interrupted execution')
            return False
        except Exception as e:
            display.error(to_unicode(e))
            #FIXME: add traceback in very very verbose mode
            return False

    def emptyline(self):
        return

    def do_shell(self, arg):
        """
        You can run shell commands through the shell module.

        eg.:
        shell ps uax | grep java | wc -l
        shell killall python
        shell halt -n

        You can use the ! to force the shell module. eg.:
        !ps aux | grep java | wc -l
        """
        self.default(arg, True)

    def do_forks(self, arg):
        """Set the number of forks"""
        if not arg:
            display.display('Usage: forks <number>')
            return
        self.options.forks = int(arg)
        self.set_prompt()

    do_serial = do_forks

    def do_verbosity(self, arg):
        """Set verbosity level"""
        if not arg:
            display.display('Usage: verbosity <number>')
        else:
            display.verbosity = int(arg)
            display.v('verbosity level set to %s' % arg)

    def do_cd(self, arg):
        """
            Change active host/group. You can use hosts patterns as well eg.:
            cd webservers
            cd webservers:dbservers
            cd webservers:!phoenix
            cd webservers:&staging
            cd webservers:dbservers:&staging:!phoenix
        """
        if not arg:
            self.options.cwd = '*'
        elif arg == '..':
            try:
                self.options.cwd = self.inventory.groups_for_host(
                    self.options.cwd)[1].name
            except Exception:
                self.options.cwd = ''
        elif arg in '/*':
            self.options.cwd = 'all'
        elif self.inventory.get_hosts(arg):
            self.options.cwd = arg
        else:
            display.display("no host matched")

        self.set_prompt()

    def do_list(self, arg):
        """List the hosts in the current group"""
        if arg == 'groups':
            for group in self.groups:
                display.display(group)
        else:
            for host in self.selected:
                display.display(host.name)

    def do_become(self, arg):
        """Toggle whether plays run with become"""
        if arg:
            self.options.become_user = arg
            display.v("become changed to %s" % self.options.become)
            self.set_prompt()
        else:
            display.display("Please specify become value, e.g. `become yes`")

    def do_remote_user(self, arg):
        """Given a username, set the remote user plays are run by"""
        if arg:
            self.options.remote_user = arg
            self.set_prompt()
        else:
            display.display(
                "Please specify a remote user, e.g. `remote_user root`")

    def do_become_user(self, arg):
        """Given a username, set the user that plays are run by when using become"""
        if arg:
            self.options.become_user = arg
        else:
            display.display(
                "Please specify a user, e.g. `become_user jenkins`")
            display.v("Current user is %s" % self.options.become_user)
        self.set_prompt()

    def do_become_method(self, arg):
        """Given a become_method, set the privilege escalation method when using become"""
        if arg:
            self.options.become_method = arg
            display.v("become_method changed to %s" %
                      self.options.become_method)
        else:
            display.display(
                "Please specify a become_method, e.g. `become_method su`")

    def do_exit(self, args):
        """Exits from the console"""
        sys.stdout.write('\n')
        return -1

    do_EOF = do_exit

    def helpdefault(self, module_name):
        if module_name in self.modules:
            in_path = module_loader.find_plugin(module_name)
            if in_path:
                oc, a, _ = module_docs.get_docstring(in_path)
                if oc:
                    display.display(oc['short_description'])
                    display.display('Parameters:')
                    for opt in oc['options'].keys():
                        display.display('  ' +
                                        stringc(opt, C.COLOR_HIGHLIGHT) + ' ' +
                                        oc['options'][opt]['description'][0])
                else:
                    display.error('No documentation found for %s.' %
                                  module_name)
            else:
                display.error(
                    '%s is not a valid command, use ? to list all valid commands.'
                    % module_name)

    def complete_cd(self, text, line, begidx, endidx):
        mline = line.partition(' ')[2]
        offs = len(mline) - len(text)

        if self.options.cwd in ('all', '*', '\\'):
            completions = self.hosts + self.groups
        else:
            completions = [
                x.name for x in self.inventory.list_hosts(self.options.cwd)
            ]

        return [
            to_str(s)[offs:] for s in completions
            if to_str(s).startswith(to_str(mline))
        ]

    def completedefault(self, text, line, begidx, endidx):
        if line.split()[0] in self.modules:
            mline = line.split(' ')[-1]
            offs = len(mline) - len(text)
            completions = self.module_args(line.split()[0])

            return [s[offs:] + '=' for s in completions if s.startswith(mline)]

    def module_args(self, module_name):
        in_path = module_loader.find_plugin(module_name)
        oc, a, _ = module_docs.get_docstring(in_path)
        return oc['options'].keys()

    def run(self):

        super(ConsoleCLI, self).run()

        sshpass = None
        becomepass = None
        vault_pass = None

        # hosts
        if len(self.args) != 1:
            self.pattern = 'all'
        else:
            self.pattern = self.args[0]
        self.options.cwd = self.pattern

        # dynamically add modules as commands
        self.modules = self.list_modules()
        for module in self.modules:
            setattr(
                self,
                'do_' + module,
                lambda arg, module=module: self.default(module + ' ' + arg))
            setattr(self,
                    'help_' + module,
                    lambda module=module: self.helpdefault(module))

        self.normalize_become_options()
        (sshpass, becomepass) = self.ask_passwords()
        self.passwords = {'conn_pass': sshpass, 'become_pass': becomepass}

        self.loader = DataLoader()

        if self.options.vault_password_file:
            # read vault_pass from a file
            vault_pass = CLI.read_vault_password_file(
                self.options.vault_password_file, loader=self.loader)
            self.loader.set_vault_password(vault_pass)
        elif self.options.ask_vault_pass:
            vault_pass = self.ask_vault_passwords()[0]
            self.loader.set_vault_password(vault_pass)

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

        if len(self.inventory.list_hosts(self.pattern)) == 0:
            # Empty inventory
            display.warning(
                "provided hosts list is empty, only localhost is available")

        self.inventory.subset(self.options.subset)
        self.groups = self.inventory.list_groups()
        self.hosts = [x.name for x in self.inventory.list_hosts(self.pattern)]

        # This hack is to work around readline issues on a mac:
        #  http://stackoverflow.com/a/7116997/541202
        if 'libedit' in readline.__doc__:
            readline.parse_and_bind("bind ^I rl_complete")
        else:
            readline.parse_and_bind("tab: complete")

        histfile = os.path.join(os.path.expanduser("~"),
                                ".ansible-console_history")
        try:
            readline.read_history_file(histfile)
        except IOError:
            pass

        atexit.register(readline.write_history_file, histfile)
        self.set_prompt()
        self.cmdloop()
Example #60
0
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)

        # Remove created temporary files
        os.remove(self.hosts.name)

        return stats