def get_play_prereqs_2(self, options): loader = DataLoader() if self.vault_pass: loader.set_vault_password(self.vault_pass) variable_manager = VariableManager() variable_manager.extra_vars = self.extra_vars variable_manager.options_vars = { 'ansible_version': self.version_info(ansible_version) } # Add this to avoid the Ansible bug: no host vars as host is not in inventory # In version 2.0.1 it must be fixed ansible.inventory.HOSTS_PATTERNS_CACHE = {} inventory = Inventory(loader=loader, variable_manager=variable_manager, host_list=options.inventory) variable_manager.set_inventory(inventory) if self.host: inventory.subset(self.host) # let inventory know which playbooks are using so it can know the # basedirs inventory.set_playbook_basedir(os.path.dirname(self.playbook_file)) return loader, inventory, variable_manager
class Inventory24(Inventory): def __init__(self, inventory, ask_vault_pass, vault_password_files, vault_ids): from ansible.cli import CLI super(Inventory24, self).__init__() loader = DataLoader() if vault_ids or vault_password_files or ask_vault_pass: CLI.setup_vault_secrets(loader, vault_ids, vault_password_files, ask_vault_pass) self.inventory = ansible.inventory.manager.InventoryManager(loader=loader, sources=inventory) self.variable_manager = VariableManager(loader=loader) self.variable_manager.set_inventory(self.inventory) # internal fuctions that actually do the work # adapted almost entirely from lib/ansible/vars/manager.py def _plugins_inventory(self, entities): import os from ansible.plugins.loader import vars_loader from ansible.utils.vars import combine_vars ''' merges all entities by inventory source ''' data = {} for inventory_dir in self.variable_manager._inventory._sources: if ',' in inventory_dir: # skip host lists continue elif not os.path.isdir(inventory_dir): # always pass 'inventory directory' inventory_dir = os.path.dirname(inventory_dir) for plugin in vars_loader.all(): data = combine_vars(data, self._get_plugin_vars(plugin, inventory_dir, entities)) return data def _get_plugin_vars(self, plugin, path, entities): from ansible.inventory.host import Host data = {} try: data = plugin.get_vars(self.variable_manager._loader, path, entities) except AttributeError: for entity in entities: if isinstance(entity, Host): data.update(plugin.get_host_vars(entity.name)) else: data.update(plugin.get_group_vars(entity.name)) return data def get_group_vars(self, group): return self._plugins_inventory([group]) def get_host_vars(self, host): try: all_vars = self.variable_manager.get_vars(host=host, include_hostvars=True) except ansible.errors.AnsibleParserError: raise NoVaultSecretFound # play, host, task, include_hostvars, include_delegate_to magic_vars = ['ansible_playbook_python', 'groups', 'group_names', 'inventory_dir', 'inventory_file', 'inventory_hostname', 'inventory_hostname_short', 'omit', 'playbook_dir'] return {k: v for (k, v) in all_vars.items() if k not in magic_vars} def get_group(self, group_name): return self.inventory.groups[group_name]
def ansible_runner_24x(playbook_path, module_path, extra_var, inventory_src, console=True): loader = DataLoader() extra_var["ansible_python_interpreter"] = sys.executable variable_manager = VariableManager(loader=loader) variable_manager.extra_vars = extra_var inventory = Inventory(loader=loader, sources=[inventory_src]) variable_manager.set_inventory(inventory) passwords = {} Options = namedtuple('Options', [ 'connection', 'module_path', 'forks', 'become', 'become_method', 'become_user', 'check', 'diff', 'listhosts', 'listtasks', 'listtags', 'syntax', 'remote_user', 'private_key_file', 'ssh_common_args', 'ssh_extra_args', 'sftp_extra_args', 'scp_extra_args', 'verbosity', ]) options = Options(listtags=False, listtasks=False, listhosts=False, syntax=False, connection='local', module_path=module_path, forks=100, remote_user='******', private_key_file=None, ssh_common_args=None, ssh_extra_args=None, sftp_extra_args=None, scp_extra_args=None, become=False, become_method='sudo', become_user='******', verbosity=4, diff=False, check=False) pbex = PlaybookExecutor(playbooks=[playbook_path], inventory=inventory, variable_manager=variable_manager, loader=loader, options=options, passwords=passwords) return pbex
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']))
def __init__(self, **kwargs): super(Ansible_playbook, self).__init__(**kwargs) self.task_file = kwargs.get('task_file', None) self.sudo = kwargs.get('sudo', False) self.sudo_user = kwargs.get('sudo_user', False) self.sudo_password = kwargs.get('sudo_password', False) # check if parameters have been provided if self._is_parameters_ok(): # since the API is constructed for CLI it expects certain options to always be set in the context object context.CLIARGS = self._get_options() # initialize needed objects loader = DataLoader() passwords = {'become_pass': self.sudo_password} inventory = InventoryManager(loader=loader, sources="localhost,") # variable manager takes care of merging all the different sources to give you a unified # view of variables available in each context variable_manager = VariableManager(loader=loader, inventory=inventory) variable_manager.set_inventory(inventory) playbooks = None with open(self.task_file, 'r') as stream: try: playbooks = yaml.full_load(stream) except yaml.YAMLError as exc: print(exc) play = Play().load(playbooks[0], variable_manager=variable_manager, loader=loader) # Run it - instantiate task queue manager, which takes care of forking and setting up all objects # to iterate over host list and tasks tqm = None try: tqm = TaskQueueManager( inventory=inventory, variable_manager=variable_manager, loader=loader, passwords=passwords, stdout_callback='default', # Use our custom callback instead of the ``default`` callback plugin, which prints to stdout ) tqm.run( play ) # most interesting data for a play is actually sent to the callback's methods finally: # we always need to cleanup child procs and the structres we use to communicate with them if tqm is not None: tqm.cleanup()
def fetch_files(self): """ Fetch files from all hosts via ansible playbook reference: https://docs.ansible.com/ansible/latest/dev_guide/developing_api.html """ loader = DataLoader() inventory = InventoryManager(loader=loader, sources=[INVENTORY_PATH]) variable_manager = VariableManager( loader=loader, inventory=inventory, ) variable_manager.set_inventory(inventory) variable_manager.extra_vars = { "data_id": self.new_id, "data_path": self.data_path, "remote_path": REMOTE_DATA_PATH } Options = namedtuple("Options", [ "connection", "forks", "become", "become_method", "become_user", "check", "listhosts", "listtasks", "listtags", "syntax", "module_path", "diff" ]) options = Options(connection="ssh", forks=100, become=True, become_method="sudo", become_user="******", check=False, listhosts=False, listtasks=False, listtags=False, syntax=False, module_path="", diff=False) passwords = dict(vault_pass="******") playbook = PlaybookExecutor(playbooks=[PLAYBOOK_PATH], inventory=inventory, loader=loader, variable_manager=variable_manager, options=options, passwords=passwords) if not self.ansible_stdout: results_callback = ResultCallback() playbook._tqm._stdout_callback = results_callback _.info("fetch_files started...") playbook.run()
class PlaybookRunner(object): def __init__(self, playbook, extra_vars, check_mode=True, verbosity=0): self.extra_vars = extra_vars self.options = Options() self.options.verbosity = verbosity self.options.connection = 'local' # Need a connection type "smart" or "ssh" self.options.become = True self.options.become_method = 'sudo' self.options.become_user = '******' self.options.check = check_mode # Set global verbosity self.display = Display() self.display.verbosity = self.options.verbosity # Executor appears to have it's own # verbosity object/setting as well playbook_executor.verbosity = self.options.verbosity # Gets data from YAML/JSON files self.loader = DataLoader() # self.loader.set_vault_password(os.environ['VAULT_PASS']) # Set inventory, using most of above objects self.inventory = InventoryManager(loader=self.loader, sources="localhost,") # All the variables from all the various places self.variable_manager = VariableManager(loader=self.loader, inventory=self.inventory) self.variable_manager.set_inventory(self.inventory) self.variable_manager.extra_vars = self.extra_vars # Playbook to run. Assumes it is local to this python file pb_dir = os.path.dirname(__file__) playbook = "%s/%s" % (pb_dir, playbook) # Setup playbook executor, but don't run until run() called self.pbex = playbook_executor.PlaybookExecutor( playbooks=[playbook], inventory=self.inventory, variable_manager=self.variable_manager, loader=self.loader, options=self.options, passwords={}) def run(self): # Results of PlaybookExecutor self.pbex.run() # noinspection PyProtectedMember stats = self.pbex._tqm._stats hosts = sorted(stats.processed.keys()) for h in hosts: t = stats.summarize(h) if t['unreachable'] > 0 or t['failures'] > 0: raise Exception("Had some failure")
def run_playbook(play: AnsiblePlay) -> int: """Run ansible playbook Args: play (AnsiblePlay): object describing the current play Returns: int: return code """ if play.inventory: env = {"ANSIBLE_HOST_KEY_CHECKING": "False"} return execute_command( [ "ansible-playbook", "-i", play.inventory, "-e", json.dumps(play.extra_vars), "--tags", ",".join(play.tags), play.playbook, ], env=env, ) context.CLIARGS = ImmutableDict( tags=play.tags, skip_tags=play.skip_tags, connection='smart', verbosity=play.verbosity, forks=10, become=None, become_method=None, become_user=None, check=False, syntax=None, start_at_task=None, diff=False, ) loader = DataLoader() variable_manager = VariableManager(loader=loader) variable_manager.extra_vars.update(play.extra_vars) inventory = InventoryManager(loader=loader) variable_manager.set_inventory(inventory) passwords = {} pbex = PlaybookExecutor( playbooks=[play.playbook], inventory=inventory, variable_manager=variable_manager, loader=loader, passwords=passwords, ) return pbex.run()
def hostsPlaybook(hosts_path, playbook_path): # 用来加载解析yaml文件或JSON内容,并且支持vault的解密 loader = DataLoader() inventory = InventoryManager(loader=loader, sources=hosts_path) # 管理变量的类,包括主机,组,扩展等变量,之前版本是在 inventory中的 variable_manager = VariableManager(loader=loader, inventory=inventory) # 把inventory传递给variable_manager管理 variable_manager.set_inventory(inventory) runner = PlayBookRunner(playbook_path, inventory=inventory) ret = runner.run() return ret
def _run_play(self, play_source, host_vars): host_list = play_source['hosts'] loader = dataloader.DataLoader() # FIXME(jpena): we need to behave differently if we are using # Ansible >= 2.4.0.0. Remove when only versions > 2.4 are supported if PRE_24_ANSIBLE: variable_manager = VariableManager() inventory_inst = Inventory(loader=loader, variable_manager=variable_manager, host_list=host_list) variable_manager.set_inventory(inventory_inst) else: inventory_inst = Inventory(loader=loader, sources=','.join(host_list) + ',') variable_manager = VariableManager(loader=loader, inventory=inventory_inst) for host, variables in host_vars.items(): host_inst = inventory_inst.get_host(host) for var_name, value in variables.items(): if value is not None: variable_manager.set_host_variable( host_inst, var_name, value) storage = [] callback = MyCallback(storage) tqm = task_queue_manager.TaskQueueManager( inventory=inventory_inst, variable_manager=variable_manager, loader=loader, options=self.options, passwords=self.passwords, stdout_callback=callback, ) # create play play_inst = play.Play().load(play_source, variable_manager=variable_manager, loader=loader) # actually run it try: tqm.run(play_inst) finally: tqm.cleanup() return storage
def ansible_runner_24x(playbook_path, extra_vars, options, inventory_src='localhost', console=True): loader = DataLoader() variable_manager = VariableManager(loader=loader) variable_manager._extra_vars = extra_vars inventory = Inventory(loader=loader, sources=[inventory_src]) variable_manager.set_inventory(inventory) passwords = {} pbex = PlaybookExecutor([playbook_path], inventory, variable_manager, loader, options, passwords) return pbex
class Inventory20(Inventory): def __init__(self, inventory, ask_vault_pass, vault_password_files, vault_ids): if vault_ids or len(vault_password_files) > 1: raise NotImplementedError from ansible.cli import CLI super(Inventory20, self).__init__() loader = DataLoader() if ask_vault_pass: self.vault_pass = CLI.ask_vault_passwords() elif vault_password_files: self.vault_pass = CLI.read_vault_password_file( vault_password_files[0], loader) if self.vault_pass is not None: loader.set_vault_password(self.vault_pass) self.variable_manager = VariableManager() try: self.inventory = ansible.inventory.Inventory( loader=loader, variable_manager=self.variable_manager, host_list=inventory) except ansible.errors.AnsibleError: raise NoVaultSecretFound self.variable_manager.set_inventory(self.inventory) def _handle_missing_return_result(self, fn, member): import inspect # http://stackoverflow.com/a/197053 vars = inspect.getargspec(fn) if 'return_results' in vars[0]: return fn(member, return_results=True) else: return fn(member) def get_group_vars(self, group): return self._handle_missing_return_result( self.inventory.get_group_vars, group) def get_host_vars(self, host): return self._handle_missing_return_result(self.inventory.get_host_vars, host) def get_group(self, group_name): return self.inventory.get_group(group_name)
def ansible_runner_24x(playbook_path, extra_vars, options=None, inventory_src='localhost', console=True): loader = DataLoader() variable_manager = VariableManager(loader=loader) variable_manager.extra_vars = extra_vars inventory = Inventory(loader=loader, sources=[inventory_src]) variable_manager.set_inventory(inventory) passwords = {} pbex = PlaybookExecutor([playbook_path], inventory, variable_manager, loader, options, passwords) return pbex
def executor(tmpdir_factory, request): playbooks = request.node.callspec.params.get('playbook') playbook_files = [] for name, playbook in playbooks.items(): filename = str(tmpdir_factory.mktemp('data').join(name)) with open(filename, 'w') as f: f.write(playbook) playbook_files.append(filename) cli = PlaybookCLI(['', 'playbook.yml']) cli.parse() options = cli.parser.parse_args(['-v'])[0] loader = DataLoader() variable_manager = VariableManager(loader=loader) inventory = InventoryManager(loader=loader, sources='localhost,') variable_manager.set_inventory(inventory) return PlaybookExecutor(playbooks=playbook_files, inventory=inventory, variable_manager=variable_manager, loader=loader, options=options, passwords={})
class Inventory20(Inventory): def __init__(self, inventory, ask_vault_pass, vault_password_files, vault_ids): if vault_ids or len(vault_password_files) > 1: raise NotImplementedError from ansible.cli import CLI super(Inventory20, self).__init__() loader = DataLoader() if ask_vault_pass: self.vault_pass = CLI.ask_vault_passwords() elif vault_password_files: self.vault_pass = CLI.read_vault_password_file(vault_password_files[0], loader) if self.vault_pass is not None: loader.set_vault_password(self.vault_pass) self.variable_manager = VariableManager() try: self.inventory = ansible.inventory.Inventory(loader=loader, variable_manager=self.variable_manager, host_list=inventory) except ansible.errors.AnsibleError: raise NoVaultSecretFound self.variable_manager.set_inventory(self.inventory) def _handle_missing_return_result(self, fn, member): import inspect # http://stackoverflow.com/a/197053 vars = inspect.getargspec(fn) if 'return_results' in vars[0]: return fn(member, return_results=True) else: return fn(member) def get_group_vars(self, group): return self._handle_missing_return_result(self.inventory.get_group_vars, group) def get_host_vars(self, host): return self._handle_missing_return_result(self.inventory.get_host_vars, host) def get_group(self, group_name): return self.inventory.get_group(group_name)
def get_play_prereqs_2(self, options): loader = DataLoader() if self.vault_pass: loader.set_vault_password(self.vault_pass) variable_manager = VariableManager() variable_manager.extra_vars = self.extra_vars variable_manager.options_vars = { 'ansible_version': self.version_info(ansible_version) } inventory = Inventory(loader=loader, variable_manager=variable_manager, host_list=options.inventory) variable_manager.set_inventory(inventory) # let inventory know which playbooks are using so it can know the # basedirs inventory.set_playbook_basedir(os.path.dirname(self.playbook_file)) return loader, inventory, variable_manager
class Runner(object): def __init__(self, hostnames, playbook, private_key_file, run_data, become_pass, verbosity=0): self.run_data = run_data self.options = Options() self.options.private_key_file = private_key_file self.options.verbosity = verbosity self.options.connection = 'ssh' # Need a connection type "smart" or "ssh" self.options.become = True self.options.become_method = 'sudo' self.options.become_user = '******' # Set global verbosity self.display = Display() self.display.verbosity = self.options.verbosity # Executor appears to have it's own # verbosity object/setting as well playbook_executor.verbosity = self.options.verbosity # Become Pass Needed if not logging in as user root passwords = {'become_pass': become_pass} # Gets data from YAML/JSON files self.loader = DataLoader() self.loader.set_vault_password(os.environ['VAULT_PASS']) # All the variables from all the various places self.variable_manager = VariableManager() self.variable_manager.extra_vars = self.run_data # Parse hosts, I haven't found a good way to # pass hosts in without using a parsed template :( # (Maybe you know how?) self.hosts = NamedTemporaryFile(delete=False) self.hosts.write("""[run_hosts] %s """ % hostnames) self.hosts.close() # This was my attempt to pass in hosts directly. # # Also Note: In py2.7, "isinstance(foo, str)" is valid for # latin chars only. Luckily, hostnames are # ascii-only, which overlaps latin charset ## if isinstance(hostnames, str): ## hostnames = {"customers": {"hosts": [hostnames]}} # Set inventory, using most of above objects self.inventory = Inventory(loader=self.loader, variable_manager=self.variable_manager, host_list=self.hosts.name) self.variable_manager.set_inventory(self.inventory) # Playbook to run. Assumes it is # local to this python file pb_dir = os.path.dirname(__file__) playbook = "%s/%s" % (pb_dir, playbook) # Setup playbook executor, but don't run until run() called self.pbex = playbook_executor.PlaybookExecutor( playbooks=[playbook], inventory=self.inventory, variable_manager=self.variable_manager, loader=self.loader, options=self.options, passwords=passwords) def run(self): # Results of PlaybookExecutor self.pbex.run() stats = self.pbex._tqm._stats # Test if success for record_logs run_success = True hosts = sorted(stats.processed.keys()) for h in hosts: t = stats.summarize(h) if t['unreachable'] > 0 or t['failures'] > 0: run_success = False # Dirty hack to send callback to save logs with data we want # Note that function "record_logs" is one I created and put into # the playbook callback file self.pbex._tqm.send_callback('record_logs', user_id=self.run_data['user_id'], success=run_success)
class AnsibleAPI(object): """ This is a General object for parallel execute modules. """ def __init__(self, resource, *args, **kwargs): self.resource = resource self.inventory = None self.variable_manager = None self.loader = None self.options = None self.passwords = None self.callback = None self.__initializeData() self.results_raw = {} def __initializeData(self): """ 初始化ansible """ Options = namedtuple('Options', [ 'connection', 'module_path', 'forks', 'timeout', 'remote_user', 'ask_pass', 'private_key_file', 'ssh_common_args', 'ssh_extra_args', 'sftp_extra_args', 'scp_extra_args', 'become', 'become_method', 'become_user', 'ask_value_pass', 'verbosity', 'check', 'listhosts', 'listtasks', 'listtags', 'syntax' ]) # initialize needed objects self.variable_manager = VariableManager() self.loader = DataLoader() self.options = Options(connection='smart', module_path='/usr/share/ansible', forks=100, timeout=10, remote_user='******', ask_pass=False, private_key_file=None, ssh_common_args=None, ssh_extra_args=None, sftp_extra_args=None, scp_extra_args=None, become=None, become_method=None, become_user='******', ask_value_pass=False, verbosity=None, check=False, listhosts=False, listtasks=False, listtags=False, syntax=False) self.passwords = dict(sshpass=None, becomepass=None) self.inventory = MyInventory(self.resource, self.loader, self.variable_manager).inventory self.variable_manager.set_inventory(self.inventory) def run(self, host_list, module_name, module_args): """ run module from andible ad-hoc. module_name: ansible module_name module_args: ansible module args """ # create play with tasks play_source = dict( name="Ansible Play", hosts=host_list, gather_facts='no', tasks=[dict(action=dict(module=module_name, args=module_args))]) play = Play().load(play_source, variable_manager=self.variable_manager, loader=self.loader) # actually run it tqm = None self.callback = ResultsCollector() try: tqm = TaskQueueManager( inventory=self.inventory, variable_manager=self.variable_manager, loader=self.loader, options=self.options, passwords=self.passwords, ) tqm._stdout_callback = self.callback tqm.run(play) finally: if tqm is not None: tqm.cleanup() def run_playbook(self, host_list, role_name, role_uuid, temp_param): """ run ansible palybook """ try: self.callback = ResultsCollector() filenames = ['' + '/handlers/ansible/v1_0/sudoers.yml' ] # playbook的路径 template_file = '' # 模板文件的路径 if not os.path.exists(template_file): sys.exit() extra_vars = { } # 额外的参数 sudoers.yml以及模板中的参数,它对应ansible-playbook test.yml --extra-vars "host='aa' name='cc' " host_list_str = ','.join([item for item in host_list]) extra_vars['host_list'] = host_list_str extra_vars['username'] = role_name extra_vars['template_dir'] = template_file extra_vars['command_list'] = temp_param.get('cmdList') extra_vars['role_uuid'] = 'role-%s' % role_uuid self.variable_manager.extra_vars = extra_vars # actually run it executor = PlaybookExecutor( playbooks=filenames, inventory=self.inventory, variable_manager=self.variable_manager, loader=self.loader, options=self.options, passwords=self.passwords, ) executor._tqm._stdout_callback = self.callback executor.run() except Exception as e: print('error: %s' % e) def get_result(self): self.results_raw = {'success': {}, 'failed': {}, 'unreachable': {}} for host, result in self.callback.host_ok.items(): self.results_raw['success'][host] = result._result for host, result in self.callback.host_failed.items(): self.results_raw['failed'][host] = result._result.get( 'msg') or result._result for host, result in self.callback.host_unreachable.items(): self.results_raw['unreachable'][host] = result._result['msg'] return self.results_raw
def run_playbook(playbook, host_list, vars): # https://github.com/celery/billiard/issues/189 # https://github.com/Mirantis/kostyor-openstack-ansible/commit/407ec033514600cd62f4931f199efd13405b0aae import multiprocessing import billiard multiprocessing.Process = billiard.Process Options = namedtuple('Options', [ 'listtags', 'listtasks', 'listhosts', 'syntax', 'connection', 'module_path', 'forks', 'remote_user', 'private_key_file', 'ssh_common_args', 'ssh_extra_args', 'sftp_extra_args', 'scp_extra_args', 'become', 'become_method', 'become_user', 'verbosity', 'check', 'diff' ]) loader = DataLoader() variable_manager = VariableManager(loader=loader) options = Options(listtags=False, listtasks=False, listhosts=False, syntax=False, connection='ssh', module_path=None, forks=100, remote_user=None, private_key_file=None, ssh_common_args=None, ssh_extra_args=None, sftp_extra_args=None, scp_extra_args=None, become=False, become_method='sudo', become_user='******', verbosity=None, check=False, diff=False) passwords = {} inventory = InventoryManager(loader=loader) inventory.add_group('ci') inventory.add_host(host_list.values()[0], 'ci') inventory.reconcile_inventory() variable_manager.set_inventory(inventory) variable_manager.extra_vars = vars playbook_path = playbook constants.HOST_KEY_CHECKING = False pbex = PlaybookExecutor(playbooks=[playbook_path], inventory=inventory, variable_manager=variable_manager, loader=loader, options=options, passwords=passwords) results = pbex.run() pubkey = None try: pubkey = variable_manager._nonpersistent_fact_cache[ host_list['ci']]['pubkey']['stdout'] except KeyError: pass return results, pubkey
class PlayBookJob(object): '''封装一个playbook接口,提供给外部使用''' def __init__(self, playbooks, ssh_user='******', passwords='null', project_name='all', ack_pass=False, forks=5, ext_vars=None): self.playbooks = playbooks # self.host_list = host_list self.ssh_user = ssh_user self.passwords = dict(vault_pass=passwords) self.project_name = project_name self.ack_pass = ack_pass self.forks = forks self.connection = 'smart' self.ext_vars = ext_vars ## 用来加载解析yaml文件或JSON内容,并且支持vault的解密 self.loader = DataLoader() # 根据inventory加载对应变量 self.inventory = InventoryManager(loader=self.loader, sources=['/etc/ansible/hosts']) # 管理变量的类,包括主机,组,扩展等变量,之前版本是在 inventory中的 self.variable_manager = VariableManager(loader=self.loader, inventory=self.inventory) self.variable_manager.extra_vars = self.ext_vars # print(self.variable_manager.get_vars()) # print(self.variable_manager.get_vars()) # 所有主机信息 self.variable_manager.set_inventory(self.inventory) # 初始化需要的对象1 self.Options = namedtuple('Options', [ 'connection', 'remote_user', 'ask_sudo_pass', 'verbosity', 'ack_pass', 'module_path', 'forks', 'become', 'become_method', 'become_user', 'check', 'listhosts', 'listtasks', 'listtags', 'syntax', 'sudo_user', 'sudo', 'diff' ]) # 初始化需要的对象2 self.options = self.Options(connection=self.connection, remote_user=self.ssh_user, ack_pass=self.ack_pass, sudo_user=self.ssh_user, forks=self.forks, sudo='yes', ask_sudo_pass=False, verbosity=5, module_path=None, become=True, become_method='sudo', become_user='******', check=None, listhosts=None, listtasks=None, listtags=None, syntax=None, diff=False) # 初始化console输出 self.callback = ResultCallback() # 直接开始 # return self.run() def get_result(self): # print(dir(self.callback)) # print("host_ok:", self.callback.host_ok) return self.callback.host_ok # def get_result(self): # self.result_all = {'success': {}, 'fail': {}, 'unreachable': {}} # # print result_all # # print dir(self.results_callback) # for host, result in self.results_callback.host_ok.items(): # self.result_all['success'][host] = result._result # # for host, result in self.results_callback.host_failed.items(): # self.result_all['failed'][host] = result._result['msg'] # # for host, result in self.results_callback.host_unreachable.items(): # self.result_all['unreachable'][host] = result._result['msg'] # # for i in self.result_all['success'].keys(): # print(i, self.result_all['success'][i]) # self.result_msg = self.callback.v2_runner_item_on_ok() # return self.result_msg # print(self.result_all['fail']) # print(self.result_all['unreachable']) def run(self): # pb = None pb = YunweiPlaybookExecutor(playbooks=self.playbooks, inventory=self.inventory, variable_manager=self.variable_manager, loader=self.loader, options=self.options, passwords=self.passwords, stdout_callback=self.callback) # pb._tqm._stdout_callback = self.callback pb.run() del pb return self.get_result()
def test_variable_manager_precedence(self): # FIXME: this needs to be redone as dataloader is not the automatic source of data anymore return # pylint: disable=unreachable ''' Tests complex variations and combinations of get_vars() with different objects to modify the context under which variables are merged. ''' # FIXME: BCS makethiswork # return True mock_inventory = MagicMock() inventory1_filedata = """ [group2:children] group1 [group1] host1 host_var=host_var_from_inventory_host1 [group1:vars] group_var = group_var_from_inventory_group1 [group2:vars] group_var = group_var_from_inventory_group2 """ fake_loader = DictDataLoader({ # inventory1 '/etc/ansible/inventory1': inventory1_filedata, # role defaults_only1 '/etc/ansible/roles/defaults_only1/defaults/main.yml': """ default_var: "default_var_from_defaults_only1" host_var: "host_var_from_defaults_only1" group_var: "group_var_from_defaults_only1" group_var_all: "group_var_all_from_defaults_only1" extra_var: "extra_var_from_defaults_only1" """, '/etc/ansible/roles/defaults_only1/tasks/main.yml': """ - debug: msg="here i am" """, # role defaults_only2 '/etc/ansible/roles/defaults_only2/defaults/main.yml': """ default_var: "default_var_from_defaults_only2" host_var: "host_var_from_defaults_only2" group_var: "group_var_from_defaults_only2" group_var_all: "group_var_all_from_defaults_only2" extra_var: "extra_var_from_defaults_only2" """, }) inv1 = InventoryManager(loader=fake_loader, sources=['/etc/ansible/inventory1']) v = VariableManager(inventory=mock_inventory, loader=fake_loader) play1 = Play.load(dict( hosts=['all'], roles=['defaults_only1', 'defaults_only2'], ), loader=fake_loader, variable_manager=v) # first we assert that the defaults as viewed as a whole are the merged results # of the defaults from each role, with the last role defined "winning" when # there is a variable naming conflict res = v.get_vars(play=play1) self.assertEqual(res['default_var'], 'default_var_from_defaults_only2') # next, we assert that when vars are viewed from the context of a task within a # role, that task will see its own role defaults before any other role's blocks = play1.compile() task = blocks[1].block[0] res = v.get_vars(play=play1, task=task) self.assertEqual(res['default_var'], 'default_var_from_defaults_only1') # next we assert the precedence of inventory variables v.set_inventory(inv1) h1 = inv1.get_host('host1') res = v.get_vars(play=play1, host=h1) self.assertEqual(res['group_var'], 'group_var_from_inventory_group1') self.assertEqual(res['host_var'], 'host_var_from_inventory_host1') # next we test with group_vars/ files loaded fake_loader.push( "/etc/ansible/group_vars/all", """ group_var_all: group_var_all_from_group_vars_all """) fake_loader.push( "/etc/ansible/group_vars/group1", """ group_var: group_var_from_group_vars_group1 """) fake_loader.push( "/etc/ansible/group_vars/group3", """ # this is a dummy, which should not be used anywhere group_var: group_var_from_group_vars_group3 """) fake_loader.push( "/etc/ansible/host_vars/host1", """ host_var: host_var_from_host_vars_host1 """) fake_loader.push( "group_vars/group1", """ playbook_group_var: playbook_group_var """) fake_loader.push( "host_vars/host1", """ playbook_host_var: playbook_host_var """) res = v.get_vars(play=play1, host=h1) # self.assertEqual(res['group_var'], 'group_var_from_group_vars_group1') # self.assertEqual(res['group_var_all'], 'group_var_all_from_group_vars_all') # self.assertEqual(res['playbook_group_var'], 'playbook_group_var') # self.assertEqual(res['host_var'], 'host_var_from_host_vars_host1') # self.assertEqual(res['playbook_host_var'], 'playbook_host_var') # add in the fact cache v._fact_cache['host1'] = dict( fact_cache_var="fact_cache_var_from_fact_cache") res = v.get_vars(play=play1, host=h1) self.assertEqual(res['fact_cache_var'], 'fact_cache_var_from_fact_cache')
class Inventory24(Inventory): def __init__(self, inventory, ask_vault_pass, vault_password_files, vault_ids): from ansible.cli import CLI super(Inventory24, self).__init__() loader = DataLoader() if vault_ids or vault_password_files or ask_vault_pass: CLI.setup_vault_secrets(loader, vault_ids, vault_password_files, ask_vault_pass) self.inventory = ansible.inventory.manager.InventoryManager( loader=loader, sources=inventory) self.variable_manager = VariableManager(loader=loader) self.variable_manager.set_inventory(self.inventory) # internal fuctions that actually do the work # adapted almost entirely from lib/ansible/vars/manager.py def _plugins_inventory(self, entities): import os from ansible.plugins.loader import vars_loader from ansible.utils.vars import combine_vars ''' merges all entities by inventory source ''' data = {} for inventory_dir in self.variable_manager._inventory._sources: if ',' in inventory_dir: # skip host lists continue elif not os.path.isdir( inventory_dir): # always pass 'inventory directory' inventory_dir = os.path.dirname(inventory_dir) for plugin in vars_loader.all(): data = combine_vars( data, self._get_plugin_vars(plugin, inventory_dir, entities)) return data def _get_plugin_vars(self, plugin, path, entities): from ansible.inventory.host import Host data = {} try: data = plugin.get_vars(self.variable_manager._loader, path, entities) except AttributeError: for entity in entities: if isinstance(entity, Host): data.update(plugin.get_host_vars(entity.name)) else: data.update(plugin.get_group_vars(entity.name)) return data def get_group_vars(self, group): return self._plugins_inventory([group]) def get_host_vars(self, host): try: all_vars = self.variable_manager.get_vars(host=host, include_hostvars=True) except ansible.errors.AnsibleParserError: raise NoVaultSecretFound # play, host, task, include_hostvars, include_delegate_to magic_vars = [ 'ansible_playbook_python', 'groups', 'group_names', 'inventory_dir', 'inventory_file', 'inventory_hostname', 'inventory_hostname_short', 'omit', 'playbook_dir' ] return {k: v for (k, v) in all_vars.items() if k not in magic_vars} def get_group(self, group_name): return self.inventory.groups[group_name]
class AnsibleController(object): """Ansible controller. The primary responsibility is for driving the execution of either modules or playbooks to configure/manage remote machines. """ def __init__(self, inventory): """Constructor. Primarily used for initializing attributes used by module/playbook execution. :param inventory: inventory file """ self.loader = DataLoader() self.ansible_inventory = inventory self.inventory = None self.variable_manager = None # module options self.module_options = namedtuple('Options', [ 'connection', 'module_path', 'forks', 'become', 'become_method', 'become_user', 'check', 'remote_user', 'private_key_file', 'diff' ]) def set_inventory(self): """Create the ansible inventory object with the supplied inventory.""" self.variable_manager = VariableManager(loader=self.loader) self.inventory = InventoryManager(loader=self.loader, sources=self.ansible_inventory) self.variable_manager.set_inventory(self.inventory) @ssh_retry def run_module(self, module, logger, script=None, run_options={}, extra_args=None, extra_vars=None, ans_verbosity=None): """ :param module: Name of the ansible module to run. :type module: str :param logger: Logger object. :type logger: logger object :param script: Absolute path a script, if using the script module. :type script: str :param run_options: additional ansible run options :type run_options: dict :param extra_args: module arguments :type extra_args: str :param extra_vars: used to determine where to run the module against :type extra_vars: dict :param ans_verbosity: verbosity to use for the ansible call. :type ans_verbosity: str :return: A tuple (rc, sterr) """ if "localhost" in extra_vars and extra_vars["localhost"]: module_call = "ansible localhost -m %s" % (module) else: module_call = "ansible -i %s %s -m %s" % \ (self.ansible_inventory, extra_vars["hosts"], module) # add extra arguments if module == "script" or module == "shell": if extra_args: module_call += " -a '%s %s'" % (script, extra_args) else: module_call += " -a '%s'" % script elif extra_args: module_call += " -a '%s'" % extra_args if run_options: for key in run_options: if key == "remote_user": module_call += " --user %s" % run_options[key] elif key == "become": if run_options[key]: module_call += " --%s" % key elif key == "tags": taglist = ','.join(run_options[key]) module_call += " --tags %s" % taglist else: module_call += " --%s %s" % (key.replace( '_', '-'), run_options[key]) if ans_verbosity: module_call += " -%s" % ans_verbosity # Set the connection if localhost if "localhost" in extra_vars and extra_vars["localhost"]: module_call += " -c local" logger.debug(module_call) output = exec_local_cmd_pipe(module_call, logger) return output @ssh_retry def run_playbook(self, playbook, logger, extra_vars=None, run_options=None, ans_verbosity=None, env_var=None): """Run an Ansible playbook. :param playbook: Playbook to call :type playbook: str :param extra_vars: Additional variables for playbook :type extra_vars: dict :param run_options: playbook run options :type run_options: dict :param ans_verbosity: ansible verbosity settings :param env_var: dict of env variables to be passed :type: env_var: dict :type ans_verbosity: str :return: A tuple (rc, sterr) """ playbook_call = "ansible-playbook -i %s %s" % \ (self.ansible_inventory, playbook) if extra_vars is not None: for key in extra_vars: if not isinstance(extra_vars[key], string_types): extra_var_dict = dict() extra_var_dict[key] = extra_vars[key] playbook_call += ' -e "%s" ' % extra_var_dict elif key == "file": playbook_call += ' -e "@%s" ' % extra_vars[key] else: playbook_call += " -e %s=\"'%s'\"" % (key, extra_vars[key]) if run_options: for key in run_options: if key == "remote_user": playbook_call += " --user %s" % run_options[key] elif key == "become": if run_options[key]: playbook_call += " --%s" % key elif key == "tags": taglist = ','.join(run_options[key]) playbook_call += " --tags %s" % taglist elif key == "skip_tags": taglist = ','.join(run_options[key]) playbook_call += " --skip-tags %s" % taglist elif key == "vault-password-file": taglist = ','.join(run_options[key]) playbook_call += " --vault-password-file %s" % taglist else: playbook_call += " --%s %s" % (key.replace( '_', '-'), run_options[key]) if ans_verbosity: playbook_call += " -%s" % ans_verbosity logger.debug(playbook_call) output = exec_local_cmd_pipe(playbook_call, logger, env_var=env_var) return output
def test_variable_manager_precedence(self): # FIXME: this needs to be redone as dataloader is not the automatic source of data anymore return # pylint: disable=unreachable ''' Tests complex variations and combinations of get_vars() with different objects to modify the context under which variables are merged. ''' # FIXME: BCS makethiswork # return True mock_inventory = MagicMock() inventory1_filedata = """ [group2:children] group1 [group1] host1 host_var=host_var_from_inventory_host1 [group1:vars] group_var = group_var_from_inventory_group1 [group2:vars] group_var = group_var_from_inventory_group2 """ fake_loader = DictDataLoader({ # inventory1 '/etc/ansible/inventory1': inventory1_filedata, # role defaults_only1 '/etc/ansible/roles/defaults_only1/defaults/main.yml': """ default_var: "default_var_from_defaults_only1" host_var: "host_var_from_defaults_only1" group_var: "group_var_from_defaults_only1" group_var_all: "group_var_all_from_defaults_only1" extra_var: "extra_var_from_defaults_only1" """, '/etc/ansible/roles/defaults_only1/tasks/main.yml': """ - debug: msg="here i am" """, # role defaults_only2 '/etc/ansible/roles/defaults_only2/defaults/main.yml': """ default_var: "default_var_from_defaults_only2" host_var: "host_var_from_defaults_only2" group_var: "group_var_from_defaults_only2" group_var_all: "group_var_all_from_defaults_only2" extra_var: "extra_var_from_defaults_only2" """, }) inv1 = InventoryManager(loader=fake_loader, sources=['/etc/ansible/inventory1']) v = VariableManager(inventory=mock_inventory, loader=fake_loader) v._fact_cache = defaultdict(dict) play1 = Play.load(dict( hosts=['all'], roles=['defaults_only1', 'defaults_only2'], ), loader=fake_loader, variable_manager=v) # first we assert that the defaults as viewed as a whole are the merged results # of the defaults from each role, with the last role defined "winning" when # there is a variable naming conflict res = v.get_vars(play=play1) self.assertEqual(res['default_var'], 'default_var_from_defaults_only2') # next, we assert that when vars are viewed from the context of a task within a # role, that task will see its own role defaults before any other role's blocks = play1.compile() task = blocks[1].block[0] res = v.get_vars(play=play1, task=task) self.assertEqual(res['default_var'], 'default_var_from_defaults_only1') # next we assert the precedence of inventory variables v.set_inventory(inv1) h1 = inv1.get_host('host1') res = v.get_vars(play=play1, host=h1) self.assertEqual(res['group_var'], 'group_var_from_inventory_group1') self.assertEqual(res['host_var'], 'host_var_from_inventory_host1') # next we test with group_vars/ files loaded fake_loader.push("/etc/ansible/group_vars/all", """ group_var_all: group_var_all_from_group_vars_all """) fake_loader.push("/etc/ansible/group_vars/group1", """ group_var: group_var_from_group_vars_group1 """) fake_loader.push("/etc/ansible/group_vars/group3", """ # this is a dummy, which should not be used anywhere group_var: group_var_from_group_vars_group3 """) fake_loader.push("/etc/ansible/host_vars/host1", """ host_var: host_var_from_host_vars_host1 """) fake_loader.push("group_vars/group1", """ playbook_group_var: playbook_group_var """) fake_loader.push("host_vars/host1", """ playbook_host_var: playbook_host_var """) res = v.get_vars(play=play1, host=h1) # self.assertEqual(res['group_var'], 'group_var_from_group_vars_group1') # self.assertEqual(res['group_var_all'], 'group_var_all_from_group_vars_all') # self.assertEqual(res['playbook_group_var'], 'playbook_group_var') # self.assertEqual(res['host_var'], 'host_var_from_host_vars_host1') # self.assertEqual(res['playbook_host_var'], 'playbook_host_var') # add in the fact cache v._fact_cache['host1'] = dict(fact_cache_var="fact_cache_var_from_fact_cache") res = v.get_vars(play=play1, host=h1) self.assertEqual(res['fact_cache_var'], 'fact_cache_var_from_fact_cache')
class Runner(object): def __init__(self, execution_id, playbook_dir, options, playbook_name, extra_vars, become_password=None): self.execution_id = execution_id self.extra_vars = extra_vars self.playbook_name = playbook_name self.options = Options() for k,v in options.iteritems(): setattr(self.options, k,v) print options # Set global verbosity self.display = Display() self.display.verbosity = self.options.verbosity # Executor appears to have it's own # verbosity object/setting as well playbook_executor.verbosity = self.options.verbosity # Become Pass Needed if not logging in as user root passwords = {'become_pass': become_password} # Gets data from YAML/JSON files self.loader = DataLoader() # Set inventory, using most of above objects temp_dir = "/home/pattabi/ansible/ansible_api_server/ansible_api_server/data" self.inventory = InventoryManager(loader=self.loader, sources=[temp_dir + "/" + "hosts"]) # All the variables from all the various places self.variable_manager = VariableManager(loader=self.loader) self.variable_manager.set_inventory(self.inventory) self.variable_manager.extra_vars = self.extra_vars # Setup playbook executor, but don't run until run() called self.pbex = playbook_executor.PlaybookExecutor( playbooks=[playbook_dir + "/" + playbook_name], inventory=self.inventory, variable_manager=self.variable_manager, loader=self.loader, options=self.options, passwords=passwords) def run(self): # Results of PlaybookExecutor self.pbex.run() stats = self.pbex._tqm._stats # Test if success for record_logs run_success = True target_hosts = sorted(stats.processed.keys()) for h in target_hosts: t = stats.summarize(h) if t['unreachable'] > 0 or t['failures'] > 0: run_success = False # Dirty hack to send callback to save logs with data we want # Note that function "record_logs" is one I created and put into # the playbook callback file self.pbex._tqm.send_callback( 'record_logs', self.execution_id, success=run_success ) return stats
class Runner(object): def __init__(self, tags, forks, *args, **kwargs): self._inventory = None self._variable_manager = None self._loader = None self._options = None self.passwords = None self.callback = None self.log_file_name = 'ansible.log' self.forks = forks self.tags = tags self._unreachable_hosts = dict() self.basepath = GET().get_log_dir() self.create_dir = CREATE() self.__initalizeData() def __initalizeData(self): ''' 初始化ansible ''' Options = namedtuple('Options', [ 'connection', 'remote_user', 'ask_sudo_pass', 'verbosity', 'ack_pass', 'module_path', 'forks', 'become', 'become_method', 'become_user', 'check', 'listhosts', 'listtasks', 'listtags', 'syntax', 'diff', 'tags', ]) self.options = Options( connection='smart', remote_user='******', ack_pass=None, forks=int(self.forks), ask_sudo_pass=False, verbosity=5, module_path=None, become=True, become_method='su', become_user='******', check=None, listhosts=False, listtasks=False, listtags=False, diff=False, syntax=None, tags=self.tags, ) self.loader = DataLoader() self.variable_manager = VariableManager(loader=self.loader) self.config_items = Config_read() self.log_path = self.create_dir.create_dir( basepath=self.basepath, extra_path=self.config_items.get_value(sections='LOGGER_DIR', key='ANSIBLE_LOG_FILE')) self.inventory = InventoryManager( loader=self.loader, sources=self.config_items.get_value( sections='ANSIBLE', key='INVENTORY_CONFIG').split(",")) self.variable_manager.set_inventory(self.inventory) self.passwords = dict(conn_pass='******', become_pass='******') ''' 运行ansible adhoc ''' def run(self, host_lists, module_name, module_args, register): self.logger = Logger(logger_name='ansible_adhoc', external_path=self.log_path) self.callback = ResultsCollector() play_source = dict(name='Ansible Play', hosts=host_lists, gather_facts='no', tasks=[ dict(action=dict(module=module_name, args=module_args), register=register) ]) play = Play().load(play_source, variable_manager=self.variable_manager, loader=self.loader) tqm = None try: tqm = TaskQueueManager( inventory=self.inventory, variable_manager=self.variable_manager, loader=self.loader, options=self.options, passwords=self.passwords, stdout_callback=self.callback, ) result = tqm.run(play) except Exception as e: print e self.logger.error(message='Ansible adhoc error: %s' % e) finally: if tqm is not None: tqm.cleanup() ''' 运行ansible playbook ''' def run_playbook(self, playbooks, ssh_user, project_name, extra_vars={}): try: self.playbookcallback = PlaybookResultsCollector() self.logger = Logger(logger_name='ansible_playbook', external_path=self.log_path) self.playbooks = playbooks if not os.path.exists(self.playbooks[0]): self.logger.error(message="Playbooks '%s' is not exist" % self.playbooks[0]) sys.exit(1) else: self.logger.debug(message="Playbooks '%s' is exist" % self.playbooks[0]) self.ssh_user = ssh_user self.project_name = project_name self.ack_pass = False self.connection = 'smart' self.extra_vars = extra_vars self.variable_manager.extra_vars = extra_vars pb = None pb = PlaybookExecutor( playbooks=self.playbooks, inventory=self.inventory, variable_manager=self.variable_manager, loader=self.loader, options=self.options, passwords=self.passwords, #tag = 'repo' ) pb._tqm._stdout_callback = self.playbookcallback result = pb.run() except Exception as e: print e self.logger.critical(message="Ansilbe playbook error:%s" % e) def get_adhoc_message(self, status, host, result): self.status = 'Status:[%s]' % status self.host = ',Remote Host:[%s]' % host if result.get('start', None): self.start_time = result['start'] else: self.start_time = None if result.get('end', None): self.end_time = result['end'] else: self.end_time = None if self.start_time is not None and self.end_time is not None: self.period = ',Period:[%s - %s]' % (self.start_time, self.end_time) else: self.period = '' if result.get('cmd', None): self.command = 'Command:[%s]' % result['cmd'] else: self.command = '' if result.get('msg', None): return_data = result.get('msg').replace("\r\n", ",") elif result.get('stdout', None): return_data = result.get('stdout').replace("\n", ",") elif result.get('stderr', None): return_data = result.get('stderr').replace("\n", ",") else: return_data = result.get('stdout').replace("\n", ",") self.return_data = ',Result:[%s]' % return_data self.message = self.status + self.host + self.period + self.command + self.return_data return self.message def get_playbook_message(self, status, host, result): self.status = 'Status:[%s]' % status self.host = ',Remote Host:[%s]' % host if result.get('msg', None): self.msg = ',Msg:[%s]' % result['msg'].replace("\r\n", ",") else: self.msg = ',Msg:[%s]' % result self.playbooks = ',Playbook:[%s]' % self.playbooks[0] self.message = self.status + self.host + self.playbooks + self.msg return self.message ''' 将callback返回的ansible执行结果,打印成日志条目 ''' def get_adhoc_result(self): self.result_raw = {'Ok': {}, 'Failures': {}, 'Unreachable': {}} for host, result in self.callback.host_ok.items(): status = 'Ok' self.get_adhoc_message(status, host, result) self.result_raw['Ok'][host] = result self.logger.info(message=self.message) for host, result in self.callback.host_failed.items(): status = 'Failures' self.get_adhoc_message(status, host, result) self.result_raw['Failures'][host] = result self.logger.error(message=self.message) for host, result in self.callback.host_unreachable.items(): print self.callback.host_unreachable status = 'Unreachable' self.get_adhoc_message(status, host, result) self.result_raw['Unreachable'][host] = result self.logger.error(message=self.message) def get_playbook_result(self): self.result_raw = { 'Unreachable': {}, 'Skipped': {}, 'Ok': {}, 'Changed': {}, 'Failures': {} } for host, result in self.playbookcallback.task_ok.items(): status = 'Ok' self.get_playbook_message(status, host, result) self.result_raw['Ok'][host] = result self.logger.info(message=self.message) for host, result in self.playbookcallback.task_skip.items(): status = 'Skip' self.get_playbook_message(status, host, result) self.result_raw['Skip'][host] = result self.logger.info(message=self.message) for host, result in self.playbookcallback.task_failed.items(): status = 'Failures' self.get_playbook_message(status, host, result) self.result_raw['Failures'][host] = result self.logger.error(message=self.message) for host, result in self.playbookcallback.task_unreachable.items(): status = 'Unreachable' self.get_playbook_message(status, host, result) self.result_raw['Unreachable'][host] = result self.logger.error(message=self.message)
class my_ansible_play(): #这里是ansible运行 #初始化各项参数,大部分都定义好,只有几个参数是必须要传入的 def __init__(self, playbooks, ssh_user='******', passwords='null', project_name='all', ack_pass=False, forks=5, ext_vars=None): self.playbooks = playbooks # self.host_list = host_list self.ssh_user = ssh_user self.passwords = dict(vault_pass=passwords) self.project_name = project_name self.ack_pass = ack_pass self.forks = forks self.connection = 'smart' self.ext_vars = ext_vars self.playbook_path = self.playbooks ## 用来加载解析yaml文件或JSON内容,并且支持vault的解密 self.loader = DataLoader() # 根据inventory加载对应变量 self.inventory = InventoryManager(loader=self.loader, sources=['/etc/ansible/hosts']) # 管理变量的类,包括主机,组,扩展等变量,之前版本是在 inventory中的 self.variable_manager = VariableManager(loader=self.loader, inventory=self.inventory) # self.variable_manager.extra_vars = {"host_list": self.host_list} self.variable_manager.extra_vars = self.ext_vars # print(self.variable_manager.get_vars()) # 所有主机信息 self.variable_manager.set_inventory(self.inventory) # 初始化需要的对象1 Options = namedtuple('Options', [ 'listtags', 'listtasks', 'listhosts', 'syntax', 'connection', 'module_path', 'forks', 'private_key_file', 'ssh_common_args', 'ssh_extra_args', 'sftp_extra_args', 'scp_extra_args', 'become', 'become_method', 'become_user', 'verbosity', 'check', 'diff' ]) self.options = Options(listtags=False, listtasks=False, listhosts=False, syntax=False, connection='ssh', module_path=None, forks=10, private_key_file=None, ssh_common_args=None, ssh_extra_args=None, sftp_extra_args=None, scp_extra_args=None, become=None, become_method=None, become_user=None, verbosity=None, check=False, diff=False) # 初始化需要的对象2 #定义运行的方法和返回值 def run(self): complex_msg = {} if not os.path.exists(self.playbook_path): code = 50000 results = { 'playbook': self.playbook_path, 'msg': self.playbook_path + ' playbook is not exist', 'flag': False } pbex = PlaybookExecutor(playbooks=[self.playbook_path], inventory=self.inventory, variable_manager=self.variable_manager, loader=self.loader, options=self.options, passwords=self.passwords) self.results_callback = mycallback() pbex._tqm._stdout_callback = self.results_callback try: code = pbex.run() except AnsibleParserError: code = 50000 results = { 'playbook': self.playbook_path, 'msg': self.playbook_path + ' playbook have syntax error', 'flag': False } return code, results if self.results_callback.status_no_hosts: code = 5000 results = { 'playbook': self.playbook_path, 'msg': self.results_callback.status_no_hosts, 'flag': False, 'executed': False } return code, results def get_result(self): self.result_all = {'success': {}, 'failed': {}, 'unreachable': {}} for host, result in self.results_callback.host_ok.items(): self.result_all['success'][host] = result._result for host, result in self.results_callback.host_failed.items(): self.result_all['failed'][host] = result._result['msg'] for host, result in self.results_callback.host_unreachable.items(): self.result_all['unreachable'][host] = result._result['msg'] # for i in self.result_all['success'].keys(): # print('Success Info', i,self.result_all['success'][i]) # print('Failed Info', self.result_all['failed']) # print('Unreachable Info', self.result_all['unreachable']) return self.result_all
Options( connection='local', module_path='cloud/amazon', forks=1, become=None, become_method=None, become_user=None, check=True, remote_user=None, private_key_file=None, ssh_common_args=None, sftp_extra_args=None, scp_extra_args=None, ssh_extra_args=None, verbosity=3, diff=False ) ) passwords = dict(vault_pass='') aws_region = 'us-west-2' # create inventory and pass to var manager inventory = InventoryManager(loader=loader) variable_manager.set_inventory(inventory) def run(play): tqm = None results = None try: tqm = TaskQueueManager( inventory=inventory, variable_manager=variable_manager, loader=loader, options=options, passwords=passwords, stdout_callback='default', ) results = tqm.run(play)
become_user=None, check=True, remote_user=None, private_key_file=None, ssh_common_args=None, sftp_extra_args=None, scp_extra_args=None, ssh_extra_args=None, verbosity=3)) passwords = dict(vault_pass='') aws_region = 'us-west-2' # create inventory and pass to var manager inventory = InventoryManager(loader=loader) variable_manager.set_inventory(inventory) def run(play): tqm = None results = None try: tqm = TaskQueueManager( inventory=inventory, variable_manager=variable_manager, loader=loader, options=options, passwords=passwords, stdout_callback='default', ) results = tqm.run(play)
class PlaybookRunner(object): """ The plabybook API. """ def __init__( self, hosts=None, # a list or dynamic-hosts, # default is /etc/ansible/hosts playbook_path=None, # * a playbook file forks=C.DEFAULT_FORKS, listtags=False, listtasks=False, listhosts=False, syntax=False, module_path=None, remote_user='******', timeout=C.DEFAULT_TIMEOUT, ssh_common_args=None, ssh_extra_args=None, sftp_extra_args=None, scp_extra_args=None, become=True, become_method=None, become_user="******", verbosity=None, extra_vars=None, connection_type="ssh", passwords=None, private_key_file=None, check=False): C.RETRY_FILES_ENABLED = False self.callbackmodule = CallbackModule() if playbook_path is None or not os.path.exists(playbook_path): raise AnsibleError("Not Found the playbook file: %s." % playbook_path) self.playbook_path = playbook_path self.inventory = MyInventory(host_list=hosts) self.loader = DataLoader() self.variable_manager = VariableManager(self.loader, self.inventory) self.passwords = passwords or {} self.options = Options(listtags=listtags, listtasks=listtasks, listhosts=listhosts, syntax=syntax, timeout=timeout, connection=connection_type, module_path=module_path, forks=forks, remote_user=remote_user, private_key_file=private_key_file, ssh_common_args=ssh_common_args or "", ssh_extra_args=ssh_extra_args or "", sftp_extra_args=sftp_extra_args, scp_extra_args=scp_extra_args, become=become, become_method=become_method, become_user=become_user, verbosity=verbosity, extra_vars=extra_vars or [], check=check, diff=False) self.variable_manager.extra_vars = load_extra_vars( loader=self.loader, options=self.options) self.variable_manager.options_vars = load_options_vars( self.options, "") self.variable_manager.set_inventory(self.inventory) self.runner = PlaybookExecutor(playbooks=[self.playbook_path], inventory=self.inventory, variable_manager=self.variable_manager, loader=self.loader, options=self.options, passwords=self.passwords) if self.runner._tqm: self.runner._tqm._stdout_callback = self.callbackmodule def run(self): if not self.inventory.list_hosts("all"): raise AnsibleError("Inventory is empty.") self.runner.run() return self.callbackmodule.output