def run_playbook(self, playbook, mode='create'): """Executes given playbook.""" playbook_path = self.playbooks_dir + '/' + playbook credentials = keystone.default_keystone_credentials() extra_vars = { 'mode': mode, 'auth_url': credentials.auth_url, 'username': credentials.username, 'project_name': credentials.project_name, 'password': credentials.project_name.password, 'image': CONF.tobiko.glance.cirros_image, 'flavor': CONF.tobiko.nova.flavor } self.variable_manager.extra_vars = extra_vars pb_executor = playbook_executor.PlaybookExecutor( playbooks=[playbook_path], inventory=self.inventory, variable_manager=self.variable_manager, loader=self.loader, options=self.options, passwords=self.passwords) pb_executor.run()
def __init__(self, playbook, run_data, private_key_file=None, verbosity=0, host_file=None): self.playbook = playbook self.run_data = run_data self.options = Options() self.options.output_file = playbook + '.result' 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() try: self.loader.set_vault_password(os.environ['VAULT_PASS']) except KeyError: pass # All the variables from all the various places self.variable_manager = VariableManager() self.variable_manager.extra_vars = {} # self.run_data # Set inventory, using most of above objects if (host_file): self.inventory = Inventory(loader=self.loader, variable_manager=self.variable_manager, host_list=host_file) else: self.inventory = Inventory(loader=self.loader, variable_manager=self.variable_manager) 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={})
def run_playbook(self, playbook_file, inventory_file=None, **kwargs): reload(constants) if not os.path.isfile(playbook_file): raise exceptions.FileNotFound(name=playbook_file) if inventory_file is None: inventory_file = self.inventory_file LOG.debug('Running with inventory file: %s', inventory_file) LOG.debug('Running with playbook file: %s', playbook_file) conn_pass = None if 'conn_pass' in kwargs: conn_pass = kwargs['conn_pass'] become_pass = None if 'become_pass' in kwargs: become_pass = kwargs['become_pass'] passwords = {'conn_pass': conn_pass, 'become_pass': become_pass} playbooks = [playbook_file] options = self._build_opt_dict(inventory_file, **kwargs) variable_manager = vars.VariableManager() loader = dataloader.DataLoader() options.extra_vars = {six.u(key): six.u(value) for key, value in options.extra_vars.items()} variable_manager.extra_vars = options.extra_vars ansible_inv = inventory.Inventory(loader=loader, variable_manager=variable_manager, host_list=options.inventory) ansible_inv.set_playbook_basedir(os.path.dirname(playbook_file)) variable_manager.set_inventory(ansible_inv) ansible_inv.subset(options.subset) pbex = playbook_executor.PlaybookExecutor( playbooks=playbooks, inventory=ansible_inv, variable_manager=variable_manager, loader=loader, options=options, passwords=passwords) self.tqm = pbex._tqm errors_callback = ErrorsCallback() self.add_callback(errors_callback) # There is no public API for adding callbacks, hence we use a private # property to add callbacks pbex._tqm._callback_plugins.extend(self._callbacks) status = pbex.run() stats = pbex._tqm._stats failed_results = errors_callback.failed_results result = self._process_stats(stats, failed_results) return result
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' self.options.become = True self.options.become_method = 'sudo' self.options.become_user = '******' self.display = Display() self.display.verbosity = self.options.verbosity playbook_executor.verbosity = self.options.verbosity # Become pass Need 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 # TODO Figure out a better way to parse hosts self.hosts = NamedTemporaryFile(delete=False) self.hosts.write("""[run_hosts] %s """ % hostnames) self.hosts.close() 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_playbook(self, playbook_file, inventory_file=None, **kwargs): reload(constants) if not os.path.isfile(playbook_file): raise exceptions.FileNotFound(name=playbook_file) if inventory_file is None: inventory_file = self.inventory_file LOG.debug('Running with inventory file: %s', inventory_file) LOG.debug('Running with playbook file: %s', playbook_file) conn_pass = None if 'conn_pass' in kwargs: conn_pass = kwargs['conn_pass'] become_pass = None if 'become_pass' in kwargs: become_pass = kwargs['become_pass'] passwords = {'conn_pass': conn_pass, 'become_pass': become_pass} playbooks = [playbook_file] options = self._build_opt_dict(inventory_file, **kwargs) if six.PY2: options.extra_vars = json.loads(json.dumps(options.extra_vars)) loader = dataloader.DataLoader() inventory = InventoryManager(loader=loader, sources=options.inventory) # create the variable manager, which will be shared throughout # the code, ensuring a consistent view of global variables variable_manager = VariableManager(loader=loader, inventory=inventory) variable_manager.extra_vars = options.extra_vars inventory.subset(options.subset) pbex = playbook_executor.PlaybookExecutor( playbooks=playbooks, inventory=inventory, variable_manager=variable_manager, loader=loader, options=options, passwords=passwords) self.tqm = pbex._tqm errors_callback = ErrorsCallback() self.add_callback(errors_callback) # There is no public API for adding callbacks, hence we use a private # property to add callbacks pbex._tqm._callback_plugins.extend(self._callbacks) try: pbex.run() except errors.AnsibleParserError as e: raise exceptions.ParsePlaybookError(msg=str(e)) stats = pbex._tqm._stats failed_results = errors_callback.failed_results result = self._process_stats(stats, failed_results) return result
def __init__( self, playbook, display, hosts='hosts', options={}, passwords={}, vault_pass=None): # Set options self.options = Options() for k, v in options.iteritems(): setattr(self.options, k, v) # Set global verbosity 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() # Set vault password 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: # Empty inventory self.display.error("Provided hosts list is empty.") sys.exit(1) self.inventory.subset(self.options.subset) if len(self.inventory.list_hosts()) == 0: # Invalid limit self.display.error("Specified limit does not match any hosts.") sys.exit(1) self.variable_manager.set_inventory(self.inventory) # import pdb; pdb.set_trace() # 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 __init__(self, hosts_file, playbook_file, cfg_file=None, vault_id=None, private_key_file=None, module_path=None, become_pass=None, verbosity=0): self.hosts_file = hosts_file self.playbook_file = playbook_file self.vault_id = vault_id if cfg_file: os.environ['ANSIBLE_CONFIG']=cfg_file self.options = Options() if private_key_file: self.options.private_key_file = private_key_file self.options.verbosity = verbosity if module_path: self.options.module_path = module_path self.options.connection = 'ssh' # set verbosity self.display = Display() self.display.verbosity = self.options.verbosity playbook_executor.verbosity = self.options.verbosity # Become Pass Needed if not logging in as user root if become_pass: self.options.become = True self.options.become_method = 'sudo' self.options.become_user = '******' passwords = {'become_pass': become_pass} else: passwords = {} # Gets data from YAML/JSON files self.loader = DataLoader() # vault secrets valut_id=name@password vault_secrets = [] if self.vault_id: vault_ids = vault_id.split(',', vault_id) if ',' in vault_id else [vault_id] for vid in vault_ids: vault_secrets.append(tuple(vid.split(',',1))) if vault_secrets: self.loader.set_vault_secrets(vault_secrets) # Set inventory, using most of above objects self.inventory = InventoryManager(loader=self.loader, sources=self.hosts_file) self.variable_manager = VariableManager(loader=self.loader, inventory=self.inventory) # Setup playbook executor, but don't run until run() called self.pbex = playbook_executor.PlaybookExecutor( playbooks=[self.playbook_file], inventory=self.inventory, variable_manager=self.variable_manager, loader=self.loader, options=self.options, passwords=passwords)
def __init__(self, playbook, inventory, run_data=None, verbosity=0, tags=None, skip_tags=None): self.run_data = run_data or {} 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.tags = tags or [] self.options.skip_tags = skip_tags or [] # 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 = {} # Gets data from YAML/JSON files self.loader = DataLoader() self.loader.set_vault_password(os.environ.get('VAULT_PASS', '')) # All the variables from all the various places 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=inventory) 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_pb(self, playbook_path, run_data=None): if run_data is not None: self.variable_manager.extra_vars = run_data pbex = playbook_executor.PlaybookExecutor( playbooks=[playbook_path], inventory=self.inventory, variable_manager=self.variable_manager, loader=self.loader, options=self.options, passwords=self.passwords) state = pbex.run() stats = pbex._tqm._stats stats_sum = dict() for host in self.hosts: t = stats.summarize(host) stats_sum[host] = t return state, stats_sum
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 __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 __init__(self, playbook, dci_context, options=None, verbosity=3): if options is None: self._options = Options() self._options.verbosity = verbosity self._options.connection = 'ssh' self._options.become = True self._options.become_method = 'sudo' self._options.become_user = '******' self._loader = dataloader.DataLoader() self._variable_manager = vars.VariableManager() task_queue_manager.display.verbosity = verbosity callback.global_display.verbosity = verbosity self._inventory = inventory.Inventory( loader=self._loader, variable_manager=self._variable_manager, host_list='/etc/ansible/hosts') self._variable_manager.set_inventory(self._inventory) # Instantiate our Callback plugin self._results_callback = DciCallback(dci_context=dci_context) self._playbook = Playbook.load(playbook, variable_manager=self._variable_manager, loader=self._loader) self._pbex = playbook_executor.PlaybookExecutor( playbooks=[playbook], inventory=self._inventory, variable_manager=self._variable_manager, loader=self._loader, options=self._options, passwords={})
def execute(self, extra_vars, server_ip): try: server_ip = str(server_ip) + "," inventory = InventoryManager(loader=self._loader, sources=server_ip) variable_manager = VariableManager(loader=self._loader, inventory=inventory) variable_manager.extra_vars.update(extra_vars) playbook_execution = playbook_executor.PlaybookExecutor( playbooks=[self.working_dir + "/playbooks/app_deploy.yaml"], inventory=inventory, variable_manager=variable_manager, loader=self._loader, passwords=self._passwords) playbook_execution.run() stats = playbook_execution._tqm._stats if stats is not None and stats is not False: result_hosts = stats.processed.keys() if result_hosts is not None and result_hosts is not False: for result_host in result_hosts: summary = stats.summarize(result_host) if summary['unreachable'] > 0 or summary[ 'failures'] > 0: return False else: return summary else: return False else: return False except Exception as er: # generate a error log self._log.error("execute - {} - {}".format(self.__class__.__name__, er)) return False
def run_playbook(self, playbook, extra_vars=None, check_result=False): """ Run an ansible playbook """ # https://stackoverflow.com/questions/27590039/running-ansible-playbook-using-python-api loader = DataLoader() if extra_vars: extra_vars = set(extra_vars) else: extra_vars = {} context.CLIARGS = ImmutableDict(tags={"classic"}, 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, extra_vars=extra_vars, scp_extra_args=None, become=True, become_method='sudo', become_user='******', verbosity=True, check=False, start_at_task=None) inventory = InventoryManager(loader=loader, sources=(self.inventory_file, )) variable_manager = VariableManager( loader=loader, inventory=inventory, version_info=CLI.version_info(gitinfo=False)) passwords = {} os.environ['TEST_ARTIFACTS'] = os.path.abspath(self.test_artifacts) self.logger.debug("TEST_ARTIFACTS = {}".format( os.environ['TEST_ARTIFACTS'])) pbex = playbook_executor.PlaybookExecutor( playbooks=[playbook], inventory=inventory, variable_manager=variable_manager, loader=loader, passwords=passwords) pbex._tqm._stdout_callback = "yaml" # pylint: disable=protected-access self.logger.info("Running playbook {}".format(playbook)) # https://stackoverflow.com/questions/10415028/how-can-i-recover-the-return-value-of-a-function-passed-to-multiprocessing-proce manager = multiprocessing.Manager() return_dict = manager.dict() run_process = multiprocessing.Process(target=_run_pbex, args=(pbex, return_dict)) run_process.start() # run playbook with timeout of 4hrs run_process.join(4 * 60 * 60) if run_process.is_alive(): self.logger.error( "Playbook has been running for too long. Aborting it.") _terminate_tree(run_process.pid) run_process.join() return_code = 124 else: if "exit_code" in return_dict: return_code = return_dict["exit_code"] else: return_code = 1 self.logger.debug("Playbook {} finished with {}".format( playbook, return_code)) if check_result: results_yml_file = "{}/results.yml".format(self.test_artifacts) # check if result matches: https://docs.fedoraproject.org/en-US/ci/standard-test-interface/ if not os.path.isfile("{}/test.log".format(self.test_artifacts)): err_msg = "Playbook finished without creating test.log" # overwrite any results.yml to make sure there is an error test_result = {} test_result['test'] = os.path.splitext( os.path.basename(playbook))[0] test_result['result'] = "fail" test_result["error_reason"] = err_msg result = {} result['results'] = [test_result] with open(results_yml_file, "w") as _file: yaml.safe_dump(result, _file) self.logger.error(err_msg) return_code = 1 if not os.path.isfile(results_yml_file): self.logger.debug( "playbook didn't create results.yml, creating one...") # playbook didn't create results.yml, so create one test_result = {} test_result['test'] = os.path.splitext( os.path.basename(playbook))[0] if return_code == 0: test_result['result'] = "pass" else: test_result['result'] = "fail" result = {} result['results'] = [test_result] with open(results_yml_file, "w") as _file: yaml.safe_dump(result, _file) self.logger.debug("parsing results.yml") with open(results_yml_file) as _file: parsed_yaml = yaml.load(_file, Loader=yaml.FullLoader) for result in parsed_yaml["results"]: if result['result'] != "pass": self.logger.debug( "{} has result {}, setting whole playbook as failed". format(result['test'], result['result'])) return_code = 1 return return_code
def __init__(self, inventory_filename, playbook, extra_vars, verbosity=0, subset=constants.DEFAULT_SUBSET): if not os.path.exists(inventory_filename): raise Exception( "Cannot find inventory_filename: {}. Current dir: {}".format( inventory_filename, os.getcwd())) if not os.path.exists(playbook): raise Exception( "Cannot find playbook: {}. Current dir: {}".format( playbook, os.getcwd())) self.options = Options() self.options.verbosity = verbosity self.options.connection = 'ssh' # Need a connection type "smart" or "ssh" self.options.subset = subset # Propagate defaults from ANSIBLE_CONFIG into options self.options.module_path = constants.DEFAULT_MODULE_PATH self.options.forks = constants.DEFAULT_FORKS self.options.ask_vault_pass = constants.DEFAULT_ASK_VAULT_PASS self.options.vault_password_files = [ constants.DEFAULT_VAULT_PASSWORD_FILE ] self.options.sudo = constants.DEFAULT_SUDO self.options.become = constants.DEFAULT_BECOME self.options.become_method = constants.DEFAULT_BECOME_METHOD self.options.become_user = constants.DEFAULT_BECOME_USER self.options.ask_sudo_pass = constants.DEFAULT_ASK_SUDO_PASS self.options.ask_su_pass = constants.DEFAULT_ASK_SU_PASS self.options.ask_pass = constants.DEFAULT_ASK_PASS self.options.private_key_file = constants.DEFAULT_PRIVATE_KEY_FILE self.options.remote_user = constants.DEFAULT_REMOTE_USER self.options.timeout = constants.DEFAULT_TIMEOUT self.options.poll_interval = constants.DEFAULT_POLL_INTERVAL self.options.force_handlers = constants.DEFAULT_FORCE_HANDLERS # 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 = {} # Gets data from YAML/JSON files self.loader = DataLoader() # All the variables from all the various places self.variable_manager = VariableManager() self.variable_manager.extra_vars = extra_vars # WARNING: this is a dirty hack to avoid a situation where creating multiple # instance of this Runner each with it's own Inventory instance was creating # a situation where we ended up with different UUID's for hosts and comparisons # were failing (see http://bit.ly/1qKmV3x) ansible.inventory.HOSTS_PATTERNS_CACHE = {} # Set inventory, using most of above objects self.inventory = Inventory(loader=self.loader, variable_manager=self.variable_manager, host_list=inventory_filename) self.inventory.subset(self.options.subset) self.variable_manager.set_inventory(self.inventory) # Setup playbook executor, but don't run until run() called logger.info("Running playbook: {}".format(playbook)) self.pbex = playbook_executor.PlaybookExecutor( playbooks=[playbook], inventory=self.inventory, variable_manager=self.variable_manager, loader=self.loader, options=self.options, passwords=passwords)
def __init__(self, hosts, playbook, verbosity='info', config={}, vars_filename='.variables', vault_password=""): required_defaults = ( 'forks', 'remote_user', 'private_key_file', 'become', 'become_method', 'become_user' ) for default in required_defaults: if default not in config: config[default] = getattr( C, 'DEFAULT_{}'.format(default.upper()) ) config['connection'] = config.get('connection', 'smart') config['ssh_common_args'] = config.get('ssh_common_args', None) config['ssh_extra_args'] = config.get('ssh_extra_args', None) config['sftp_extra_args'] = config.get('sftp_extra_args', None) config['scp_extra_args'] = config.get('scp_extra_args', None) config['extra_vars'] = config.get('extra_vars', {}) config['diff'] = config.get('diff', False) config['listhosts'] = config.get('listhosts', False) config['listtasks'] = config.get('listtasks', False) config['listtags'] = config.get('listtags', False) config['syntax'] = config.get('syntax', False) config['verbosity'] = VERBOSITY.get(verbosity) config['module_path'] = './' config['check'] = False self.options = options_as_class(config) # create default data loader self.loader = DataLoader() # self.loader.set_vault_password(vault_password) variables = {} try: variables = self.loader.load_from_file(vars_filename) except Exception: pass # loading inventory self.inventory = InventoryManager( loader=self.loader, sources=None ) for group in hosts.keys(): self.inventory.add_group(group) for host in hosts[group]: self.inventory.add_host(host=host, group=group) # create variable manager self.vm = VariableManager( loader=self.loader, inventory=self.inventory ) self.vm.extra_vars = variables # create a playbook executor self.pbex = playbook_executor.PlaybookExecutor( playbooks=[playbook], inventory=self.inventory, variable_manager=self.vm, loader=self.loader, options=self.options, passwords={} ) self.result_callback = JsonResultCallback() # self.result_callback.set_options(self.options) self.pbex._tqm._callback_plugins.append(self.result_callback) pass
def __init__(self, username, playbook, private_key_file, inventory_data, extra_vars, become_pass, verbosity=0, search_filter=None): """ Args: username: string, username of user running the playbook playbook: string, full playbook path eg. /tmp/my_pb.yml private_key_file: string, private key file inventory_data: dict, inventory data extra_vars: dict, Ansible extra vars, key = variable name become_pass: string, become password verbosity: integer, verbosity level search_filter: string, hosts/groups to match """ self.playbook = playbook self.username = username self.inventory_data = inventory_data self.extra_vars = extra_vars self.search_filter = search_filter 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() # ORIGNAL on line 1 #self.loader.set_vault_password(os.environ['VAULT_PASS']) self.loader.set_vault_password('secret') # All the variables from all the various places self.variable_manager = VariableManager() # Set of hosts hosts = set() # Load group variable for group in self.inventory_data: if group != '_meta': for host in self.inventory_data[group]['hosts']: host_obj = Host(host) hosts.add(host) for var in self.inventory_data[group]['vars']: self.variable_manager.set_host_variable( host_obj, var, self.inventory_data[group]['vars'][var]) # Load host variables for host in self.inventory_data['_meta']['hostvars']: for var in self.inventory_data['_meta']['hostvars'][host]: host_obj = Host(host) self.variable_manager.set_host_variable( host_obj, var, self.inventory_data['_meta']['hostvars'][host][var]) self.variable_manager.extra_vars = self.extra_vars # Set inventory, using most of above objects self.inventory = Inventory(loader=self.loader, variable_manager=self.variable_manager, host_list=list(hosts)) self.variable_manager.set_inventory(self.inventory) # Setup playbook executor, but don't run until run() called self.pbex = playbook_executor.PlaybookExecutor( playbooks=[self.playbook], inventory=self.inventory, variable_manager=self.variable_manager, loader=self.loader, options=self.options, passwords=passwords)
def __init__(self, playbook, inventory, run_data, start_at_task, step, private_key_file, become_pass, verbosity=0): self.run_data = run_data self.options = Options() self.options.listtags = False self.options.listtasks = False self.options.listhosts = False self.options.syntax = False self.options.check = False self.options.diff = False self.options.start_at_task = start_at_task self.options.step = step 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 = False self.options.become_method = 'sudo' self.options.become_user = '******' self.options.remote_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 # 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 inventory_dir = '/etc/ansible/inventory' inventory_source = "%s/%s" % (inventory_dir, inventory) self.inventory = InventoryManager(loader=self.loader, sources=inventory_source) self.variable_manager = VariableManager(loader=self.loader, inventory=self.inventory) if self.run_data: self.variable_manager.extra_vars = self.run_data['extra_vars'] self.options.tags = self.run_data['tags'] # Playbook to run. Assumes it is # local to this python file pb_dir = '/etc/ansible/playbooks' playbook = "%s/%s" % (pb_dir, playbook) print(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.get_config(), passwords=passwords)
def __init__(self, hostnames, action, playbook, private_key_file, run_data, internal_data, location, become_pass, request_id, started_at, config, dbsession, tr, verbosity=5): self.logger = app.logger self.logger.debug('initializing ansible runbook executor') self.action = action self.config = config self.dbsession = dbsession self.transition_request = tr self.location = location self.run_data = run_data self.internal_data = internal_data self.run_variables = {} self.run_variables.update(self.run_data) self.run_variables.update(self.location) self.run_variables.update(self.internal_data) self.logger.debug(str(self.location)) self.logger.debug(str(self.run_data)) self.logger.debug(str(self.run_variables)) self.request_id = request_id self.started_at = started_at self.finished_at = None self.resInstance = {} # NEW 2.9 # handles options now context.CLIARGS = ImmutableDict( connection='ssh', module_path=['/var/alm_ansible_rm/library'], forks=20, become=None, become_method='sudo', become_user='******', check=False, diff=False, ansible_python_interpreter='/usr/bin/python3', host_key_checking=False, vault_password_file='/etc/ansible/tslvault.txt', private_key_file=private_key_file, listhosts=None, listtasks=None, listtags=None, syntax=None, start_at_task=None) # Gets data from YAML/JSON files self.loader = DataLoader() self.loader.set_vault_secrets([ ('default', VaultSecret(_bytes=to_bytes('TSLDem0'))) ]) # create temporary inventory file self.hosts = NamedTemporaryFile(delete=False) self.hosts.write(b'[run_hosts]\n') self.hosts.write( b'localhost ansible_connection=local ansible_python_interpreter="/usr/bin/env python3" host_key_checking=False' ) self.hosts.close() # set Inventory self.inventory = InventoryManager(loader=self.loader, sources=self.hosts.name) # All the variables from all the various places self.variable_manager = VariableManager(loader=self.loader, inventory=self.inventory) # MOD 2.9 - has been renamed, not sure this is the proposed way to treat extra_vars, but it works self.variable_manager._extra_vars = self.run_variables # Become Pass Needed if not logging in as user root passwords = {'become_pass': become_pass} # 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, passwords=passwords) if (self.transition_request) and (isinstance(self.transition_request, TransitionRequest)): # log only if transition request, not for netowrk/image scans) self.logger.debug('transition request ' + str(self.transition_request)) self.log_request_status('PENDING', 'playbook initialized', '', '') self.logger.debug('ansible runbook executor instantiated for ' + str(playbook)) self.callback = OutputCallback(self.action, self.logger) self.pbex._tqm._stdout_callback = self.callback
def run_playbook(self, group, playbook, private_key_file, run_data, become_pas, tags=[]): """ """ # All the variables from all the various places self.variable_manager.extra_vars = run_data self.variable_manager.group_vars_files = u'%s/group_vars' % self.inventory #print self.variable_manager.get_vars(self.loader) # set options self.options.tags = tags self.options.limit = group #self.options.become = True #self.options.become_user = u'root' #self.options.private_key_file = u'%s/.ssh/id_rsa' % self.inventory # Parse hosts '''hosts = NamedTemporaryFile(delete=False) hosts.write(u'[%s]\n' % group) for host in self.get_inventory(group): hosts.write(u'%s ansible_ssh_private_key_file=%s ansible_user=root\n' % (host, self.options.private_key_file)) hosts.close() # copy .ssh key in tmp os.symlink(u'%s/.ssh' % self.inventory, u'/tmp/.ssh')''' # Set inventory, using most of above objects #inventory = InventoryManager(self.loader, sources=self.inventory) inventory = Inventory(loader=self.loader, variable_manager=self.variable_manager, host_list=self.inventory) #logger.warn(inventory.list_groups()) inventory.subset(group) logger.warn(inventory.list_groups()) logger.warn(inventory.list_hosts(group)) self.variable_manager.set_inventory(inventory) # Setup playbook executor, but don't run until run() called self.pbex = playbook_executor.PlaybookExecutor( playbooks=[playbook], inventory=inventory, variable_manager=self.variable_manager, loader=self.loader, options=self.options, passwords=None) # Results of PlaybookExecutor self.pbex.run() stats = self.pbex._tqm._stats # Test if success for record_logs run_success = True ihosts = sorted(stats.processed.keys()) for h in ihosts: t = stats.summarize(h) if t[u'unreachable'] > 0 or t[u'failures'] > 0: run_success = False # Remove created temporary files #os.remove(hosts.name) #os.remove(u'/tmp/.ssh') return stats
def __init__(self, hostnames, playbook, run_data, tags=None, become_pass=False, hostfile=None, private_key_file=None, verbosity=0): self.run_data = run_data self.options = Options() # self.options.private_key_file = private_key_file #self.options.verbosity = verbosity self.options.verbosity = 5 self.options.connection = 'smart' # Need a connection type "smart" or "ssh" self.options.become = None #self.options.remote_user = '******' self.options.become_method = None self.options.become_user = None self.options.tags = tags self.options.check = False # Set global verbosity self.display = Display() self.display.verbosity = 5 # 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.inventory = Inventory(loader=self.loader, variable_manager=self.variable_manager, host_list=hostfile) 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=None)
def __init__( self, playbooks, tags, # must have extra_vars, hostnames='127.0.0.1', connection='local', # smart|ssh|local private_key_file='', become_pass='', vault_pass='', verbosity=0, debug=False): self.debug = debug self.options = Options() self.options.tags = tags, self.options.private_key_file = private_key_file self.options.verbosity = verbosity self.options.connection = connection self.options.become = True self.options.become_method = 'sudo' self.options.become_user = '******' self.options.extra_vars = extra_vars # 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(vault_pass) # All the variables from all the various places self.variable_manager = VariableManager() self.variable_manager.extra_vars = extra_vars # 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, mode='wt') self.hosts.write("""[run_hosts]\n%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 and relative to this python file # in "../../../playbooks" directory. dirname = os.path.dirname(__file__) or '.' pb_rel_dir = '../../../playbooks' playbook_path = os.path.join(dirname, pb_rel_dir) self.options.module_path = os.path.join(playbook_path, 'library') # os.environ['ANSIBLE_CONFIG'] = os.path.abspath(os.path.dirname(__file__)) pbs = [os.path.join(playbook_path, pb) for pb in playbooks] # Setup playbook executor, but don't run until run() called self.pbex = playbook_executor.PlaybookExecutor( playbooks=pbs, inventory=self.inventory, variable_manager=self.variable_manager, loader=self.loader, options=self.options, passwords=passwords) # TODO: so here we construct a CLI line. # For whatever reason, api is not taking account for `tags`!! self.callme = [ 'ansible-playbook', '-i', self.hosts.name, ','.join(pbs), ] if tags: self.callme += ['--tags', ','.join(tags)] if extra_vars: extra = ["%s=%s" % (k, v) for k, v in extra_vars.items()] self.callme += ['--extra-vars', '"%s"' % (' '.join(extra))] if self.options.module_path: self.callme += ['--module-path', self.options.module_path]
def __init__(self, connection, private_key_file, hostnames, playbook, run_data, verbosity=4): self.run_data = run_data self.options = Options() self.options.private_key_file = private_key_file self.options.remote_user = "******" self.options.ssh_extra_args = "-vvvv -oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null" self.options.sftp_extra_args = self.options.ssh_extra_args self.options.verbosity = verbosity self.options.connection = connection #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 self.variable_manager.verbosity = verbosity self.variable_manager.ssh_extra_args = "-vvvv -oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null" # Parse hosts, I haven't found a good way to # pass hosts in without using a parsed template :( # (Maybe you know how?) self.hosts = ",".join(hostnames) self.hosts += "," # 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) 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" % 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=None)
def run_ansible_on_host(host, logger, config): from ansible.plugins.callback import CallbackBase # A rough logger that logs dict messages to standard logger class ResultCallback(CallbackBase): def __init__(self): super(ResultCallback, self).__init__() def v2_runner_on_ok(self, result, **kwargs): self.log('ok :' + str(result._result), info=True) def v2_runner_on_failed(self, result, **kwargs): self.log(result._result, info=True) def v2_runner_on_skipped(self, result, **kwargs): self.log(result._result, info=True) def v2_runner_on_unreachable(self, result, **kwargs): self.log(result._result, info=True) def v2_playbook_on_no_hosts_matched(self, *args, **kwargs): self.log('no hosts matched!') def v2_playbook_on_no_hosts_remaining(self, *args, **kwargs): self.log('NO MORE HOSTS LEFT') def v2_playbook_on_task_start(self, task, **kwargs): self.log('starting task: ' + str(task)) def v2_playbook_on_start(self, playbook, **kwargs): self.log('starting playbook' + str(playbook), info=True) def v2_playbook_on_play_start(self, play, **kwargs): self.log('starting play' + str(play), info=True) def v2_playbook_on_stats(self, stats, info=True, **kwargs): self.log('STATS FOR PLAY') hosts = sorted(stats.processed.keys()) hosts.extend(stats.failures.keys()) hosts.extend(stats.dark.keys()) hosts.extend(stats.changed.keys()) hosts.extend(stats.skipped.keys()) hosts.extend(stats.ok.keys()) for h in hosts: t = stats.summarize(h) self.log(str(t)) def log(self, param, info=False): if not info: logger.debug(str(param)) else: logger.info(str(param)) from ansible.parsing.dataloader import DataLoader from ansible.inventory import Inventory, Group, Host from ansible.executor import playbook_executor from ansible.vars import VariableManager from collections import namedtuple Options = namedtuple('Options', [ 'connection', 'module_path', 'forks', 'become', 'become_method', 'become_user', 'check', 'ansible_user', 'listhosts', 'listtasks', 'listtags', 'syntax', 'ssh_private_key_file', 'host_key_checking' ]) options = Options(connection='ssh', become=True, become_method='sudo', become_user='******', check=False, module_path=None, forks=100, ansible_user='******', listhosts=False, listtasks=False, listtags=False, syntax=False, ssh_private_key_file=PEBBLES_SSH_KEY_LOCATION, host_key_checking=False) variable_manager = VariableManager() loader = DataLoader() a_host = Host(name=host['private_ip']) a_host.set_variable('ansible_host', host['private_ip']) a_group = Group(name='notebook_host') a_group.add_host(a_host) inventory = Inventory(loader=loader, variable_manager=variable_manager, host_list=[host['private_ip']]) inventory.add_group(a_group) variable_manager.set_inventory(inventory) logger.debug('HOST:') logger.debug(a_host.serialize()) logger.debug('HOSTs from inventory:') # for some reason setting these before adding the host to inventory didn't work so well # ToDo: read up on variable_manager and figure out a more elegant way to set the variables for h_ in inventory.get_hosts(): h_.set_variable('ansible_user', 'cloud-user') h_.set_variable('ansible_ssh_common_args', '-o StrictHostKeyChecking=no') h_.set_variable('ansible_ssh_private_key_file', '/home/pebbles/.ssh/id_rsa') extra_vars = dict() extra_vars['ansible_ssh_extra_args'] = '-o StrictHostKeyChecking=no' if 'DD_HOST_DATA_VOLUME_DEVICE' in config: extra_vars['notebook_host_block_dev_path'] = config[ 'DD_HOST_DATA_VOLUME_DEVICE'] variable_manager.extra_vars = extra_vars pb_executor = playbook_executor.PlaybookExecutor( playbooks=[ '/webapps/pebbles/source/ansible/notebook_playbook.yml' ], inventory=inventory, variable_manager=variable_manager, loader=loader, options=options, passwords=None) rescb = ResultCallback() pb_executor._tqm._stdout_callback = rescb logger.info('_prepare_host(): running ansible') logger.info('_prepare_host(): inventory hosts') for h_ in inventory.get_hosts(): logger.info(h_.serialize()) logger.info(h_.get_vars()) pb_executor.run() stats = pb_executor._tqm._stats run_success = True hosts_list = sorted(stats.processed.keys()) if len(hosts_list) == 0: logger.debug('no hosts handled') for h in hosts_list: t = stats.summarize(h) logger.debug(t) logger.debug(h) if t['unreachable'] > 0 or t['failures'] > 0: run_success = False if run_success: logger.debug('_prepare_host(): run successfull') else: logger.debug('_prepare_host(): run failed') if getattr(pb_executor, '_unreachable_hosts', False): logger.debug('UNREACHABLE HOSTS ' + str(pb_executor._unreachable_hosts)) if getattr(pb_executor, '_failed_hosts', False): logger.debug('FAILED_HOSTS ' + str(pb_executor._failed_hosts)) raise RuntimeError('run_ansible_on_host(%s) failed' % host['id']) logger.debug('_prepare_host(): done running ansible')
from ansible.vars.manager import VariableManager loader = DataLoader() inventory = InventoryManager(loader=loader, sources='localhost,') extra_vars = {'name': 'create'} variable_manager = VariableManager(loader=loader, inventory=inventory) variable_manager.extra_vars = extra_vars Options = namedtuple('Options', ['connection', 'module_path', 'forks', 'become', 'become_method', 'become_user', 'check', 'diff', 'listhosts', 'listtasks', 'listtags', 'syntax']) options = Options(connection='local', module_path=['/to/mymodules'], forks=10, become=None, become_method=None, become_user=None, check=False, diff=False, listhosts=False, listtasks=False, listtags=False, syntax=False) passwords = dict(vault_pass='******') pb_executor = playbook_executor.PlaybookExecutor( playbooks=['test.yaml'], inventory=inventory, variable_manager=variable_manager, loader=loader, options=options, passwords=passwords) pb_executor.run()
def run(playbook, inventory, variables, remote_user, remote_pass=None, become_method="sudo", become_user="******", verbosity=0): """ Execute an Ansible playbook. Args: playbook (str): path to playbook to be executed inventory (list or dict): list of IP addresses or resolvable host names, OR dictionary of group name keys whose values contain a list of IP addresses or resolvable host names variables (dict): Ansible variables to use with the playbook remote_user (str): host_list credential username remote_pass (str): host_list credential password become_method (str): method used to become another user after logging in. See http://docs.ansible.com/ansible/become.html#new-command-line-options for more information become_user (str): name of user to become after logging in. See http://docs.ansible.com/ansible/become.html#new-command-line-options for more information. verbosity (int): how verbose to make stdout output, 5 is very verbose Returns: list of changed hosts Raises: curie.anteater.FailureError: if any hosts generate an error curie.anteater.UnreachableError: if any hosts are unreachable """ logger.debug( "Running playbook %r with inventory=%r, variables=%r, " "verbosity=%r.", playbook, inventory, variables, verbosity) opts = Options({ "become": False, "become_user": become_user, "become_method": become_method, "diff": False, "remote_user": remote_user, "verbosity": verbosity }) passwords = dict(conn_pass=remote_pass) try: loader = DataLoader() if isinstance(inventory, dict): inventory_manager = _create_inventory(loader, groups=inventory) elif isinstance(inventory, list): inventory_manager = _create_inventory(loader, host_list=inventory) else: raise AnteaterError("Unable to parse inventory type %r: %r" % (type(inventory), inventory)) variable_manager = VariableManager(loader=loader, inventory=inventory_manager) variable_manager.extra_vars = variables # Set display.logger and verbosity on modules, have to do this per-module. display.logger = logger ssh.display.verbosity = verbosity pbe.C.DEFAULT_SCP_IF_SSH = True pbe.C.HOST_KEY_CHECKING = False execution = pbe.PlaybookExecutor([playbook], inventory=inventory_manager, variable_manager=variable_manager, loader=loader, options=opts, passwords=passwords) execution.run() changed_hosts = _check_playbook_result(playbook, execution) logger.debug("Ansible playbook %r changed hosts: %r", playbook, changed_hosts) return changed_hosts except AnsibleError as err: raise AnteaterError(err.message)