def get_ansible_variablemanager(self, **kwargs): from ansible.parsing.dataloader import DataLoader from ansible.utils.vars import load_extra_vars from ansible.vars.manager import VariableManager if 'options' in kwargs: options = kwargs['options'] else: options = AnsibleOptions() if 'loader' in kwargs: loader = kwargs['loader'] else: loader = DataLoader() vault_secret = get_vault_password_source(self.master.main_config) if not isinstance(vault_secret, NullSource): loader.set_vault_secrets([(vault_secret.id, vault_secret)]) basedir = get_playbooks_directory(self.master.ctrl.config) loader.set_basedir(basedir) if 'inventory' in kwargs: inventory = kwargs['inventory'] else: inventory = self.get_ansible_inventorymanager() if 'variable_manager' in kwargs: variable_manager = kwargs['variable_manager'] else: variable_manager = VariableManager(loader=loader, inventory=inventory) variable_manager.extra_vars = load_extra_vars(loader=loader, options=options) return (options, loader, inventory, variable_manager)
def _play_prereqs(): options = context.CLIARGS # all needs loader loader = DataLoader() basedir = options.get('basedir', False) if basedir: loader.set_basedir(basedir) add_all_plugin_dirs(basedir) AnsibleCollectionConfig.playbook_paths = basedir default_collection = _get_collection_name_from_path(basedir) if default_collection: display.warning(u'running with default collection {0}'.format(default_collection)) AnsibleCollectionConfig.default_collection = default_collection vault_ids = list(options['vault_ids']) default_vault_ids = C.DEFAULT_VAULT_IDENTITY_LIST vault_ids = default_vault_ids + vault_ids vault_secrets = CLI.setup_vault_secrets(loader, vault_ids=vault_ids, vault_password_files=list(options['vault_password_files']), ask_vault_pass=options['ask_vault_pass'], auto_prompt=False) loader.set_vault_secrets(vault_secrets) # create the inventory, and filter it based on the subset specified (if any) inventory = InventoryManager(loader=loader, sources=options['inventory'], cache=(not options.get('flush_cache'))) # 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, version_info=CLI.version_info(gitinfo=False)) return loader, inventory, variable_manager
def _play_prereqs(): options = context.CLIARGS # all needs loader loader = DataLoader() basedir = options.get('basedir', False) if basedir: loader.set_basedir(basedir) add_all_plugin_dirs(basedir) set_collection_playbook_paths(basedir) vault_ids = list(options['vault_ids']) default_vault_ids = C.DEFAULT_VAULT_IDENTITY_LIST vault_ids = default_vault_ids + vault_ids vault_secrets = CLI.setup_vault_secrets(loader, vault_ids=vault_ids, vault_password_files=list(options['vault_password_files']), ask_vault_pass=options['ask_vault_pass'], auto_prompt=False) loader.set_vault_secrets(vault_secrets) # create the inventory, and filter it based on the subset specified (if any) 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, version_info=CLI.version_info(gitinfo=False)) return loader, inventory, variable_manager
def ansible_template( basedir: str, varname: Any, templatevars: Any, **kwargs: Any ) -> Any: dl = DataLoader() dl.set_basedir(basedir) templar = Templar(dl, variables=templatevars) return templar.template(varname, **kwargs)
def _play_prereqs(options): # all needs loader loader = DataLoader() basedir = getattr(options, 'basedir', False) if basedir: loader.set_basedir(basedir) vault_ids = options.vault_ids default_vault_ids = C.DEFAULT_VAULT_IDENTITY_LIST vault_ids = default_vault_ids + vault_ids vault_secrets = CLI.setup_vault_secrets(loader, vault_ids=vault_ids, vault_password_files=options.vault_password_files, ask_vault_pass=options.ask_vault_pass, auto_prompt=False) loader.set_vault_secrets(vault_secrets) # create the inventory, and filter it based on the subset specified (if any) 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) # load vars from cli options variable_manager.extra_vars = load_extra_vars(loader=loader, options=options) variable_manager.options_vars = load_options_vars(options, CLI.version_info(gitinfo=False)) return loader, inventory, variable_manager
def _load_defaults(inventory_path, extra_vars=None, tags=None, basedir=False): """Load common defaults data structures. For factorization purpose.""" extra_vars = extra_vars or {} tags = tags or [] loader = DataLoader() if basedir: loader.set_basedir(basedir) inventory = Inventory(loader=loader, sources=inventory_path) variable_manager = VariableManager(loader=loader, inventory=inventory) # seems mandatory to load group_vars variable if basedir: variable_manager.safe_basedir = True if extra_vars: variable_manager.extra_vars = extra_vars # NOTE(msimonin): The ansible api is "low level" in the # sense that we are redefining here all the default values # that are usually enforce by ansible called from the cli 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", "remote_user", "verbosity", "check", "tags", "diff", "basedir" ]) options = Options(listtags=False, listtasks=False, listhosts=False, syntax=False, connection="ssh", module_path=None, forks=100, private_key_file=None, ssh_common_args=None, ssh_extra_args=None, sftp_extra_args=None, scp_extra_args=None, become=None, become_method="sudo", become_user="******", remote_user=None, verbosity=2, check=False, tags=tags, diff=None, basedir=basedir) return inventory, variable_manager, loader, options
def ansible_template(basedir: str, varname: Any, templatevars: Any, **kwargs: Any) -> Any: # `basedir` is the directory containing the lintable file. # Therefore, for tasks in a role, `basedir` has the form # `roles/some_role/tasks`. On the other hand, the search path # is `roles/some_role/{files,templates}`. As a result, the # `tasks` part in the basedir should be stripped stripped. if os.path.basename(basedir) == 'tasks': basedir = os.path.dirname(basedir) dl = DataLoader() dl.set_basedir(basedir) templar = Templar(dl, variables=templatevars) return templar.template(varname, **kwargs)
def template(hostvars, srcdir): loader = DataLoader() loader.set_basedir(srcdir) templar = Templar(variables=hostvars, loader=loader) templar._fail_on_lookup_errors = True templar._fail_on_filter_errors = True return templar.template(hostvars, convert_bare=False, preserve_trailing_newlines=True, escape_backslashes=True, fail_on_undefined=False, convert_data=False, static_vars=None, cache=True, disable_lookups=False)
def role_vars(): parser.add_argument( '--playbook_path', help='Test Playbook path for role - usually role/tests/test.yml', required=True) parser.add_argument( '--vault_password_file', help='Vault password file - usually role/tests/test.yml') args = parser.parse_args() variable_manager = VariableManager() loader = DataLoader() if args.vault_password_file: # read vault_pass from a file vault_pass = CLI.read_vault_password_file(args.vault_password_file, loader=loader) loader.set_vault_password(vault_pass) playbook_path = args.playbook_path if not os.path.exists(playbook_path): print('[ERROR] The playbook does not exist') sys.exit(1) pb = Playbook.load(playbook_path, variable_manager=variable_manager, loader=loader) plays = pb.get_plays() if len(plays) == 0: print('[ERROR] No plays in playbook') sys.exit(1) first_play = plays[0] if first_play._included_path is not None: loader.set_basedir(first_play._included_path) else: loader.set_basedir(pb._basedir) result = dict() for role in first_play.roles: result.update(role.get_default_vars()) result.update(role.get_vars()) print(json.dumps(result))
def run(self, tmp=None, task_vars=None): if task_vars is None: task_vars = dict() results = super(ActionModule, self).run(tmp, task_vars) actor_name = self._task.args['name'] actor_repository = self._templar.template('{{ actor_repository }}') is_local = self._play_context.connection == 'local' task_vars['actor_remote_repo_path'] = actor_repository loader = DataLoader() loader.set_basedir(actor_repository) results.setdefault('ansible_facts', {}).setdefault( 'actor_inputs', self._task.args.setdefault('inputs', {})) results['ansible_facts']['actor_outputs'] = {} return self._perform(results, actor_name, loader, is_local)
def __init__(self, inventory_generator): """ :type inventory_generator: ops.inventory.generator.InventoryGenerator """ self.inventory_generator = inventory_generator self.generated_path, self.ssh_config_path = inventory_generator.generate() # clean up variables cache for tests ansible_vars.VARIABLE_CACHE = dict() ansible_vars.HOSTVARS_CACHE = dict() ansible_inventory.HOSTS_PATTERNS_CACHE = dict() loader = DataLoader() loader.set_basedir(self.generated_path) self.inventory = InventoryManager(loader=loader, sources=[self.generated_path]) self.variable_manager = VariableManager(loader=loader, inventory=self.inventory)
def _play_prereqs(): options = context.CLIARGS # all needs loader loader = DataLoader() basedir = options.get('basedir', False) if basedir: loader.set_basedir(basedir) vault_ids = list(options['vault_ids']) default_vault_ids = C.DEFAULT_VAULT_IDENTITY_LIST vault_ids = default_vault_ids + vault_ids vault_secrets = CLI.setup_vault_secrets( loader, vault_ids=vault_ids, vault_password_files=list(options['vault_password_files']), ask_vault_pass=options['ask_vault_pass'], auto_prompt=False) loader.set_vault_secrets(vault_secrets) # create the inventory, and filter it based on the subset specified (if any) 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) # If the basedir is specified as the empty string then it results in cwd being used. This # is not a safe location to load vars from if options.get('basedir', False) is not False: if basedir: variable_manager.safe_basedir = True else: variable_manager.safe_basedir = True # load vars from cli options variable_manager.extra_vars = load_extra_vars(loader=loader) variable_manager.options_vars = load_options_vars( CLI.version_info(gitinfo=False)) return loader, inventory, variable_manager
def main(): display = Display(verbosity=settings.DEFAULT_ANSIBLE_VERBOSITY) results_callback = CallbackModule() results_callback._display = display loader = DataLoader() loader.set_basedir(basedir_2) # create inventory, use path to host config file as source # or hosts in a comma separated string inventory = InventoryManager(loader=loader, sources='192.168.245.9,') # variable manager takes care of merging all the different sources # to give you a unifed view of variables available in each context variable_manager = VariableManager(loader=loader, inventory=inventory) variable_manager.extra_vars = extra_vars_2 play_source = loader.load_from_file(play_source_2)[0] # play_source['ansible_ssh_user'] = "******" # play_source['ansible_ssh_private_key_file'] = "/home/user/.ssh/id_rsa" # Create play object, playbook objects use .load instead of init or new methods, # this will also automatically create the task objects from the info provided in play_source play = Play().load(play_source, variable_manager=variable_manager, loader=loader) tqm = None try: tqm = TaskQueueManager( inventory=inventory, variable_manager=variable_manager, loader=loader, options=options, passwords={}, stdout_callback=results_callback, ) result = tqm.run(play) print(result) finally: if tqm is not None: tqm.cleanup() # Remove ansible tmpdir shutil.rmtree(C.DEFAULT_LOCAL_TMP, True)
def _play_prereqs(self, options): loader = DataLoader() basedir = getattr(options, 'basedir', False) if basedir: loader.set_basedir(basedir) inventory = self.inventory variable_manager = VariableManager(loader=loader, inventory=inventory) if hasattr(options, 'basedir'): if options.basedir: variable_manager.safe_basedir = True else: variable_manager.safe_basedir = True # load vars from cli options # variable_manager._extra_vars = load_extra_vars(loader=loader) # variable_manager.options_vars = load_options_vars('2.8.4') return loader, inventory, variable_manager
def play_vars(): parser.add_argument('--playbook_path', help='Playbook path', required=True) parser.add_argument('--play_name', help='Play Name', required=True) args = parser.parse_args() variable_manager = VariableManager() loader = DataLoader() # host12_vars = variable_manager.get_vars(loader=loader, host=inventory.parser.groups[args.host_name]) playbook_path = args.playbook_path if not os.path.exists(playbook_path): print('[ERROR] The playbook does not exist') sys.exit() # # Options = namedtuple('Options', ['listtags', 'listtasks', 'listhosts', 'syntax', 'connection','module_path', 'forks', 'remote_user', 'private_key_file', 'ssh_common_args', 'ssh_extra_args', 'sftp_extra_args', 'scp_extra_args', 'become', 'become_method', 'become_user', 'verbosity', 'check']) # options = Options(listtags=False, listtasks=False, listhosts=False, syntax=False, connection='ssh', module_path=None, forks=100, remote_user='******', private_key_file=None, ssh_common_args=None, ssh_extra_args=None, sftp_extra_args=None, scp_extra_args=None, become=True, become_method=None, become_user='******', verbosity=None, check=False) # # # variable_manager.extra_vars = {'hosts': 'mywebserver'} # This can accomodate various other command line arguments.` # # passwords = {} # pb = Playbook.load(playbook_path, variable_manager=variable_manager, loader=loader) plays = pb.get_plays() for play in plays: if play._included_path is not None: loader.set_basedir(play._included_path) else: loader.set_basedir(pb._basedir) result = variable_manager.get_vars(loader=loader, play=play) # pbex = PlaybookExecutor(playbooks=[playbook_path], inventory=inventory, variable_manager=variable_manager, loader=loader, options=options, passwords=passwords) # results = pbex.run() print(json.dumps(result))
from octans import Service, Conf from octans.ansible.ansible_callback import SyncCallbackModule from octans.logger import LogManager from octans.worker.task import Task from _ast import IsNot _Options = namedtuple('Options', [ 'connection', 'module_path', 'forks', 'timeout', 'remote_user', 'private_key_file', 'ssh_common_args', 'ssh_extra_args', 'sftp_extra_args', 'scp_extra_args', 'become', 'become_method', 'become_user', 'verbosity', 'check' ]) _Loader = DataLoader() _Loader.set_basedir("./ansible") Logger = LogManager.get_logger("AnsibleTask") def _get_ssh_key(ip): """ get ssh_private_key content from api :param ip: target ip :return: content in str """ ret = requests.get(Conf.get("get_key_url") + str(ip), timeout=5) if ret.ok: if ret.content is None:
class Ansible: """Easy access to Ansible API Example: >>> ansible = Ansible() >>> results = ansible.run("host1,host2", module="debug", msg="foo") >>> for host, result in results.items(): ... print(host, result['msg']) host1 foo host2 foo """ def __init__(self, connection=C.DEFAULT_TRANSPORT, inventory=C.DEFAULT_HOST_LIST, basedir=None, forks=10, stdout_callback=C.DEFAULT_STDOUT_CALLBACK, remote_user=C.DEFAULT_REMOTE_USER): self.connection = connection self.remote_user = remote_user self.module_path = [] self.forks = forks self.become = None self.become_method = None self.become_user = None self.check = False self.diff = False self.loader = DataLoader() if basedir: self.loader.set_basedir(basedir) self.inventory = InventoryManager(loader=self.loader, sources=inventory) self.variable_manager = VariableManager(loader=self.loader, inventory=self.inventory) if basedir: self.variable_manager.safe_basedir = True if stdout_callback is None: stdout_callback = 'null' tqm = TaskQueueManager(inventory=self.inventory, variable_manager=self.variable_manager, loader=self.loader, options=self, passwords=None, stdout_callback=stdout_callback, run_additional_callbacks=False) result_callback = ResultCallback() tqm._callback_plugins.append(result_callback) @atexit.register def cleanup_tqm(): tqm.cleanup() self.tqm = tqm self.results = result_callback.results def reset(self): if self.tqm is not None: self.tqm.cleanup() self.variable_manager = VariableManager(loader=self.loader, inventory=self.inventory) result_callback = ResultCallback() self.tqm = TaskQueueManager( inventory=self.inventory, variable_manager=self.variable_manager, loader=self.loader, options=self, passwords=None, stdout_callback=result_callback, ) self.results = result_callback.results def run(self, hosts, module, _arg=None, *, serial=None, **kwargs): """Runs a single action on hosts""" results = self.run_play( None, hosts, tasks=[ dict(action=dict(module=module, args=_arg if _arg else kwargs)) ], serial=serial) return dict( (host, host_results[-1]) for host, host_results in results.items()) def run_role(self, hosts: str, role: str, serial=None, **kwargs): """Runs a role on hosts with `kwargs` as additional variables""" role = dict(role=role) role.update(kwargs) return self.run_play(None, hosts, roles=[role], serial=serial) def run_play(self, name: str, hosts: str, tasks=[], roles=[], gather_facts: bool = None, serial=None, **kwargs): """runs a play on hosts""" play_dict = dict(name=name, hosts=hosts, tasks=tasks, roles=roles) if roles or gather_facts: play_dict['gather_facts'] = 'yes' else: play_dict['gather_facts'] = 'no' if serial: play_dict['serial'] = serial play_dict.update(kwargs) play = Play.load(play_dict, variable_manager=self.variable_manager, loader=self.loader) self.tqm.run(play) return self.results
def get_loader(self, base_dir='../playbooks'): loader = DataLoader( ) # Takes care of finding and reading yml, json and ini files loader.set_basedir(base_dir) return loader
def ansible_template(basedir, varname, templatevars, **kwargs): dl = DataLoader() dl.set_basedir(basedir) templar = Templar(dl, variables=templatevars) return templar.template(varname, **kwargs)
def path_dwim(basedir, given): dl = DataLoader() dl.set_basedir(basedir) return dl.path_dwim(given)
def ansible_template(basedir, varname, templatevars, **kwargs): dl = DataLoader() dl.set_basedir(basedir) templar = Templar(dl, variables=templatevars) return templar.template(varname, **kwargs)
def path_dwim(basedir, given): dl = DataLoader() dl.set_basedir(basedir) return dl.path_dwim(given)
def apply_template(value, ctx, overrides=None): if not isinstance(value, six.string_types): msg = f"Error rendering template: source must be a string, not {type(value)}" if ctx.strict: raise UnfurlError(msg) else: return f"<<{msg}>>" value = value.strip() # implementation notes: # see https://github.com/ansible/ansible/test/units/template/test_templar.py # dataLoader is only used by _lookup and to set _basedir (else ./) if not ctx.templar or (ctx.base_dir and ctx.templar._basedir != ctx.base_dir): # we need to create a new templar loader = DataLoader() if ctx.base_dir: loader.set_basedir(ctx.base_dir) if ctx.templar and ctx.templar._loader._vault.secrets: loader.set_vault_secrets(ctx.templar._loader._vault.secrets) templar = Templar(loader) ctx.templar = templar else: templar = ctx.templar overrides = Templar.find_overrides(value, overrides) if overrides: # returns the original values overrides = templar._apply_templar_overrides(overrides) templar.environment.trim_blocks = False # templar.environment.lstrip_blocks = False fail_on_undefined = ctx.strict if not fail_on_undefined: templar.environment.undefined = UnfurlUndefined vars = _VarTrackerDict(__unfurl=ctx, __python_executable=sys.executable) if hasattr(ctx.currentResource, "attributes"): vars['SELF'] = ctx.currentResource.attributes vars.update(ctx.vars) vars.ctx = ctx # replaces current vars # don't use setter to avoid isinstance(dict) check templar._available_variables = vars oldvalue = value index = ctx.referenced.start() # set referenced to track references (set by Ref.resolve) # need a way to turn on and off try: # strip whitespace so jinija native types resolve even with extra whitespace # disable caching so we don't need to worry about the value of a cached var changing # use do_template because we already know it's a template try: value = templar.template(value, fail_on_undefined=fail_on_undefined) except Exception as e: msg = str(e) match = re.search(r"has no attribute '(\w+)'", msg) if match: msg = f'missing attribute or key: "{match.group(1)}"' value = f"<<Error rendering template: {msg}>>" if ctx.strict: logger.debug(value, exc_info=True) raise UnfurlError(value) else: logger.warning(value[2:100] + "... see debug log for full report") logger.debug(value, exc_info=True) if ctx.task: ctx.task._errors.append( UnfurlTaskError(ctx.task, msg) ) else: if value != oldvalue: ctx.trace("successfully processed template:", value) external_result = None for result in ctx.referenced.getReferencedResults(index): if is_sensitive(result): # note: even if the template rendered a list or dict # we still need to wrap the entire result as sensitive because we # don't know how the referenced senstive results were transformed by the template ctx.trace("setting template result as sensitive") # mark the template result as sensitive return wrap_sensitive_value(value) if result.external: external_result = result if ( external_result and ctx.wantList == "result" and value == external_result.external.get() ): # return the external value instead return external_result # wrap result as AnsibleUnsafe so it isn't evaluated again return wrap_var(value) finally: ctx.referenced.stop() if overrides: # restore original values templar._apply_templar_overrides(overrides) return value
def run(self): super(PlaybookCLI, self).run() # Note: slightly wrong, this is written so that implicit localhost # Manage passwords sshpass = None becomepass = None vault_pass = None passwords = {} # initial error check, to make sure all specified playbooks are accessible # before we start running anything through the playbook executor for playbook in self.args: if not os.path.exists(playbook): raise AnsibleError("the playbook: %s could not be found" % playbook) if not (os.path.isfile(playbook) or stat.S_ISFIFO(os.stat(playbook).st_mode)): raise AnsibleError("the playbook: %s does not appear to be a file" % playbook) # don't deal with privilege escalation or passwords when we don't need to if not self.options.listhosts and not self.options.listtasks and not self.options.listtags and not self.options.syntax: self.normalize_become_options() (sshpass, becomepass) = self.ask_passwords() passwords = { 'conn_pass': sshpass, 'become_pass': becomepass } loader = DataLoader() if self.options.vault_password_file: # read vault_pass from a file vault_pass = CLI.read_vault_password_file(self.options.vault_password_file, loader=loader) loader.set_vault_password(vault_pass) elif self.options.ask_vault_pass: vault_pass = self.ask_vault_passwords() loader.set_vault_password(vault_pass) # create the variable manager, which will be shared throughout # the code, ensuring a consistent view of global variables variable_manager = VariableManager() variable_manager.extra_vars = load_extra_vars(loader=loader, options=self.options) variable_manager.options_vars = load_options_vars(self.options) # create the inventory, and filter it based on the subset specified (if any) inventory = Inventory(loader=loader, variable_manager=variable_manager, host_list=self.options.inventory) variable_manager.set_inventory(inventory) # (which is not returned in list_hosts()) is taken into account for # warning if inventory is empty. But it can't be taken into account for # checking if limit doesn't match any hosts. Instead we don't worry about # limit if only implicit localhost was in inventory to start with. # # Fix this when we rewrite inventory by making localhost a real host (and thus show up in list_hosts()) no_hosts = False if len(inventory.list_hosts()) == 0: # Empty inventory display.warning("provided hosts list is empty, only localhost is available") no_hosts = True inventory.subset(self.options.subset) if len(inventory.list_hosts()) == 0 and no_hosts is False: # Invalid limit raise AnsibleError("Specified --limit does not match any hosts") # flush fact cache if requested if self.options.flush_cache: self._flush_cache(inventory, variable_manager) # create the playbook executor, which manages running the plays via a task queue manager pbex = PlaybookExecutor(playbooks=self.args, inventory=inventory, variable_manager=variable_manager, loader=loader, options=self.options, passwords=passwords) results = pbex.run() if isinstance(results, list): for p in results: display.display('\nplaybook: %s' % p['playbook']) for idx, play in enumerate(p['plays']): if play._included_path is not None: loader.set_basedir(play._included_path) else: pb_dir = os.path.realpath(os.path.dirname(p['playbook'])) loader.set_basedir(pb_dir) msg = "\n play #%d (%s): %s" % (idx + 1, ','.join(play.hosts), play.name) mytags = set(play.tags) msg += '\tTAGS: [%s]' % (','.join(mytags)) if self.options.listhosts: playhosts = set(inventory.get_hosts(play.hosts)) msg += "\n pattern: %s\n hosts (%d):" % (play.hosts, len(playhosts)) for host in playhosts: msg += "\n %s" % host display.display(msg) all_tags = set() if self.options.listtags or self.options.listtasks: taskmsg = '' if self.options.listtasks: taskmsg = ' tasks:\n' def _process_block(b): taskmsg = '' for task in b.block: if isinstance(task, Block): taskmsg += _process_block(task) else: if task.action == 'meta': continue all_tags.update(task.tags) if self.options.listtasks: cur_tags = list(mytags.union(set(task.tags))) cur_tags.sort() if task.name: taskmsg += " %s" % task.get_name() else: taskmsg += " %s" % task.action taskmsg += "\tTAGS: [%s]\n" % ', '.join(cur_tags) return taskmsg all_vars = variable_manager.get_vars(loader=loader, play=play) play_context = PlayContext(play=play, options=self.options) for block in play.compile(): block = block.filter_tagged_tasks(play_context, all_vars) if not block.has_tasks(): continue taskmsg += _process_block(block) if self.options.listtags: cur_tags = list(mytags.union(all_tags)) cur_tags.sort() taskmsg += " TASK TAGS: [%s]\n" % ', '.join(cur_tags) display.display(taskmsg) return 0 else: return results
try: yield finally: os.chdir(oldcwd) root = Path(__file__).resolve().parents[1] with chdir(root): from ansible.cli import CLI from ansible.constants import DEFAULT_VAULT_IDENTITY_LIST from ansible.parsing.dataloader import DataLoader from ansible.parsing.vault import VaultLib data_loader = DataLoader() data_loader.set_basedir(root) vault_lib = VaultLib( CLI.setup_vault_secrets(data_loader, DEFAULT_VAULT_IDENTITY_LIST, auto_prompt=False)) def load_vault(path): with chdir(root): return yaml.load(vault_lib.decrypt(Path(path).read_text()), Loader=yaml.SafeLoader) class OutputFormat(str, Enum): BARE = "bare"
def path_dwim(basedir: str, given: str) -> str: dl = DataLoader() dl.set_basedir(basedir) return dl.path_dwim(given)
class AnsibleTest(object): def __init__(self): self.loader = None self.inventory = None self.vars_manager = None self.play = None self.role = None def load(self, inventory_dir, inventory_name, playbook_dir, playbook_name, play_name, role_name): self.loader = DataLoader() self.loader.set_basedir(playbook_dir) self.inventory = InventoryManager(loader=self.loader, sources=os.path.join( inventory_dir, inventory_name)) self.vars_manager = VariableManager(loader=self.loader, inventory=self.inventory) self.play = self.get_play_by_name(playbook_name, play_name) self.role = self.get_role_by_name(self.play, role_name) def get_play_by_name(self, playbook_name, play_name): playbook = Playbook.load(os.path.join(self.loader.get_basedir(), playbook_name), variable_manager=self.vars_manager, loader=self.loader) plays = playbook.get_plays() play = None for p in plays: if p.get_name() == play_name: play = p break if play is None: raise Exception("no play with name %s found in plays: %s" % (play_name, plays)) return play def get_role_by_name(self, play, role_name): roles = play.get_roles() for r in roles: if r.get_name() == role_name: return r raise Exception("no role with name %s found in roles: %s" % (role_name, roles)) def read_role_template(self, template_name): path = os.path.join(self.role._role_path, "templates", template_name) with open(path, 'r') as f: return f.read() def get_host_vars(self, host_name): all_vars = self.vars_manager.get_vars( play=self.play, host=self.inventory.get_host(host_name)) host_vars = HostVars( inventory=self.inventory, variable_manager=self.vars_manager, loader=self.loader, ) all_vars.update(dict(hostvars=host_vars)) return all_vars
def applyTemplate(value, ctx, overrides=None): if not isinstance(value, six.string_types): msg = "Error rendering template: source must be a string, not %s" % type( value) if ctx.strict: raise UnfurlError(msg) else: return "<<%s>>" % msg value = value.strip() # implementation notes: # see https://github.com/ansible/ansible/test/units/template/test_templar.py # dataLoader is only used by _lookup and to set _basedir (else ./) if not ctx.templar or (ctx.baseDir and ctx.templar._basedir != ctx.baseDir): # we need to create a new templar loader = DataLoader() if ctx.baseDir: loader.set_basedir(ctx.baseDir) if ctx.templar and ctx.templar._loader._vault.secrets: loader.set_vault_secrets(ctx.templar._loader._vault.secrets) templar = Templar(loader) ctx.templar = templar else: templar = ctx.templar overrides = Templar.findOverrides(value, overrides) if overrides: # returns the original values overrides = templar._applyTemplarOverrides(overrides) templar.environment.trim_blocks = False # templar.environment.lstrip_blocks = False fail_on_undefined = ctx.strict vars = _VarTrackerDict(__unfurl=ctx) vars.update(ctx.vars) vars.ctx = ctx # replaces current vars # don't use setter to avoid isinstance(dict) check templar._available_variables = vars oldvalue = value index = ctx.referenced.start() # set referenced to track references (set by Ref.resolve) # need a way to turn on and off try: # strip whitespace so jinija native types resolve even with extra whitespace # disable caching so we don't need to worry about the value of a cached var changing # use do_template because we already know it's a template try: value = templar.template(value, fail_on_undefined=fail_on_undefined) except Exception as e: value = "<<Error rendering template: %s>>" % str(e) if ctx.strict: logger.debug(value, exc_info=True) raise UnfurlError(value) else: logger.warning(value[2:100] + "... see debug log for full report") logger.debug(value, exc_info=True) else: if value != oldvalue: ctx.trace("successfully processed template:", value) for result in ctx.referenced.getReferencedResults(index): if isSensitive(result): # note: even if the template rendered a list or dict # we still need to wrap the entire result as sensitive because we # don't know how the referenced senstive results were transformed by the template ctx.trace("setting template result as sensitive") return wrapSensitiveValue( value, templar._loader._vault ) # mark the template result as sensitive if isinstance(value, Results): # mapValue now because wrap_var() fails with Results types value = mapValue(value, ctx, applyTemplates=False) # wrap result as AnsibleUnsafe so it isn't evaluated again return wrap_var(value) finally: ctx.referenced.stop() if overrides: # restore original values templar._applyTemplarOverrides(overrides) return value
def set_base_dir(self, baseDir): self._baseDir = baseDir if not self._templar or self._templar._basedir != baseDir: loader = DataLoader() loader.set_basedir(baseDir) self._templar = Templar(loader)