def run(self, terms, variables=None, **kwargs): self.set_options(direct=kwargs) rstrip = self.get_option('rstrip') use_base64 = self.get_option('base64') input_type = self.get_option('input_type') output_type = self.get_option('output_type') ret = [] for term in terms: display.debug("Sops lookup term: %s" % term) lookupfile = self.find_file_in_search_path(variables, 'files', term) display.vvvv(u"Sops lookup using %s as file" % lookupfile) if not lookupfile: raise AnsibleLookupError( "could not locate file in lookup: %s" % to_native(term)) try: output = Sops.decrypt(lookupfile, display=display, rstrip=rstrip, decode_output=not use_base64, input_type=input_type, output_type=output_type) except SopsError as e: raise AnsibleLookupError(to_native(e)) if use_base64: output = to_native(base64.b64encode(output)) ret.append(output) return ret
async def entry_point(cls, terms, options): session = None if not options.get("vcenter_hostname"): raise AnsibleLookupError("vcenter_hostname cannot be empty") if not options.get("vcenter_username"): raise AnsibleLookupError("vcenter_username cannot be empty") if not options.get("vcenter_password"): raise AnsibleLookupError("vcenter_password cannot be empty") try: session = await open_session( vcenter_hostname=options.get("vcenter_hostname"), vcenter_username=options.get("vcenter_username"), vcenter_password=options.get("vcenter_password"), validate_certs=bool(options.get("vcenter_validate_certs")), log_file=options.get("vcenter_rest_log_file"), ) except EmbeddedModuleFailure as e: raise AnsibleLookupError( f'Unable to connect to vCenter or ESXi API at {options.get("vcenter_hostname")}: {to_native(e)}' ) lookup = cls(options) lookup._options["session"] = session if not terms: raise AnsibleLookupError("No object has been specified.") task = asyncio.ensure_future(lookup.moid(terms[0])) return await task
def run(self, terms, variables=None, **kwargs): result = [] self.set_options(var_options=variables, direct=kwargs) not_found = self.get_option('result_not_found') no_version = self.get_option('result_no_version') for term in terms: if not FQCN_RE.match(term): raise AnsibleLookupError( '"{term}" is not a FQCN'.format(term=term)) try: collection_pkg = import_module( 'ansible_collections.{fqcn}'.format(fqcn=term)) except ImportError: # Collection not found result.append(not_found) continue try: data = load_collection_meta(collection_pkg, no_version=no_version) except Exception as exc: raise AnsibleLookupError( 'Error while loading metadata for {fqcn}: {error}'.format( fqcn=term, error=exc)) result.append(data.get('version', no_version)) return result
def run(self, terms, variables=None, **kwargs): """Generate list.""" result = [] if len(terms) > 0: templar = Templar(loader=self._templar._loader) data = [] vars_so_far = set() for index, term in enumerate(terms): if not isinstance(term, Mapping): raise AnsibleLookupError( 'Parameter {index} must be a dictionary, got {type}'. format(index=index, type=type(term))) if len(term) != 1: raise AnsibleLookupError( 'Parameter {index} must be a one-element dictionary, got {count} elements' .format(index=index, count=len(term))) k, v = list(term.items())[0] if k in vars_so_far: raise AnsibleLookupError( 'The variable {key!r} appears more than once'.format( key=k)) vars_so_far.add(k) if isinstance(v, string_types): data.append((k, v, None)) elif isinstance(v, (Sequence, Mapping)): data.append((k, None, v)) else: raise AnsibleLookupError( 'Parameter {key!r} (index {index}) must have a value of type string, dictionary or list, got type {type}' .format(index=index, key=k, type=type(v))) self.__process(result, data, 0, {}, templar, variables) return result
def run(self, terms, variables, **kwargs): if len(terms) < 2: raise AnsibleLookupError( "missing either 'data' or 'criteria' value in lookup input," " refer ansible.utils.validate lookup plugin documentation for details" ) params = {"data": terms[0], "criteria": terms[1]} if kwargs.get("engine"): params.update({"engine": kwargs["engine"]}) valid, argspec_result, updated_params = check_argspec( DOCUMENTATION, "validate lookup", schema_conditionals=ARGSPEC_CONDITIONALS, **params) if not valid: raise AnsibleLookupError( "{argspec_result} with errors: {argspec_errors}".format( argspec_result=argspec_result.get("msg"), argspec_errors=argspec_result.get("errors"), )) validator_engine, validator_result = load_validator( engine=updated_params["engine"], data=updated_params["data"], criteria=updated_params["criteria"], plugin_vars=variables, kwargs=kwargs, ) if validator_result.get("failed"): raise AnsibleLookupError( "validate lookup plugin failed with errors: {validator_result}" .format(validator_result=validator_result.get("msg"))) try: result = validator_engine.validate() except AnsibleError as exc: raise AnsibleLookupError( to_text(exc, errors="surrogate_then_replace")) except Exception as exc: raise AnsibleLookupError( "Unhandled exception from validator '{validator}'. Error: {err}" .format( validator=updated_params["engine"], err=to_text(exc, errors="surrogate_then_replace"), )) return to_list(result.get("errors", []))
def etcd3_client(client_params): try: etcd = etcd3.client(**client_params) etcd.status() except Exception as exp: raise AnsibleLookupError('Cannot connect to etcd cluster: %s' % (to_native(exp))) return etcd
def run(self, terms, variables, **kwargs): skip = False skip, total_search = self.build_paths_to_search(skip, terms) all_files_found = [] for fn in total_search: try: fn = self._templar.template(fn) except (AnsibleUndefinedVariable, UndefinedError): continue # get subdir if set by task executor, default to files otherwise subdir = getattr(self, '_subdir', 'files') path = None path = self.find_file_in_search_path(variables, subdir, fn, ignore_missing=True) if path is not None: all_files_found.append(path) if len(all_files_found)>0: return all_files_found if skip: return [] raise AnsibleLookupError("No file was found when using with_file_found. Use the 'skip: true' option to allow this task to be skipped if no " "files are found")
def run(self, terms, variables=None, **kwargs): if len(terms) > 1: raise AnsibleLookupError("must be a uid, not a list") try: uid = int(terms[0]) except ValueError: raise AnsibleLookupError("must be an integer") with open('/etc/passwd', 'r') as f: for line in f: user = line.split(':') if int(user[2]) == uid: return [user[0]] return None
def get_random(random_generator, chars, length): if not chars: raise AnsibleLookupError( "Available characters cannot be None, please change constraints" ) return "".join( random_generator.choice(chars) for dummy in range(length))
def run(self, terms, variables=None, **kwargs): if not HAS_BS: msg = missing_required_lib("beautifulsoup4", url="https://pypi.org/project/beautifulsoup4/") msg += ". Import Error: %s" % BS_IMP_ERR raise AnsibleLookupError(msg) self.set_options(var_options=variables, direct=kwargs) all_updates = self.get_option('all') architecture = self.get_option('architecture') ascending = self.get_option('ascending') product = self.get_option('product') sort = self.get_option('sort') if sort: # Map the lookup plugin's option title choices to the actual titles as returned in the XML. sort = { 'title': 'Title', 'products': 'Products', 'classification': 'Classification', 'last_updated': 'Last Updated', 'version': 'Version', 'size': 'Size', }[sort] ret = [] for search in terms: for update in find_updates(search, all_updates, sort=sort, sort_reverse=not ascending): if product and product not in update.products: continue if architecture and architecture.lower() != update.architecture.lower(): continue ret.append(update) return ret
def _run(self, args, expected_rc=0): p = Popen([self.cli_path] + args, stdout=PIPE, stderr=PIPE, stdin=PIPE) out, err = p.communicate() rc = p.wait() if rc != expected_rc: raise AnsibleLookupError(err) return out, err
def run(self, terms, variables, **kwargs): total_search, skip = self._process_terms(terms, variables, kwargs) # NOTE: during refactor noticed that the 'using a dict' as term # is designed to only work with 'one' otherwise inconsistencies will appear. # see other notes below. # actually search subdir = getattr(self, '_subdir', 'files') path = None for fn in total_search: try: fn = self._templar.template(fn) except (AnsibleUndefinedVariable, UndefinedError): continue # get subdir if set by task executor, default to files otherwise path = self.find_file_in_search_path(variables, subdir, fn, ignore_missing=True) # exit if we find one! if path is not None: return [path] # if we get here, no file was found if skip: # NOTE: global skip wont matter, only last 'skip' value in dict term return [] raise AnsibleLookupError("No file was found when using first_found.")
def run(self, terms, variables=None, **kwargs): if not HAS_XKCDPASS: raise AnsibleLookupError( "Python xkcdpass library is required. " 'Please install using "pip install xkcdpass"') self.set_options(var_options=variables, direct=kwargs) method = self.get_option("case") delimiter = self.get_option("delimiter") max_length = self.get_option("max_length") min_length = self.get_option("min_length") numwords = self.get_option("numwords") words = xp.locate_wordfile() wordlist = xp.generate_wordlist(max_length=max_length, min_length=min_length, wordfile=words) values = xp.generate_xkcdpassword(wordlist, case=method, delimiter=delimiter, numwords=numwords) return [values]
def get_token(self): # If the config file exists, assume an initial signin has taken place and try basic sign in if os.path.isfile(self.config_file_path): if not self.master_password: raise AnsibleLookupError( 'Unable to sign in to 1Password. master_password is required.' ) try: args = ['signin', '--output=raw'] if self.subdomain: args = ['signin', self.subdomain, '--output=raw'] rc, out, err = self._run(args, command_input=to_bytes( self.master_password)) self.token = out.strip() except AnsibleLookupError: self.full_login() else: # Attempt a full sign in since there appears to be no existing sign in self.full_login()
def _run(self, expected_rc=0): p = Popen([self.rand_subnet], stdout=PIPE, stderr=PIPE, stdin=PIPE) out, err = p.communicate() rc = p.wait() if rc != expected_rc: raise AnsibleLookupError(err) return out, err
def run(self, terms, variables=None, **kwargs): #self.set_options(var_options=variables, direct=kwargs) for _, name in socket.if_nameindex(): interface = gateway = None try: interface, gateway = get_interfaceinfo(name) if ( interface.is_link_local or interface.is_loopback or interface.is_multicast or interface.is_reserved ): continue break except: continue if interface is None: raise AnsibleLookupError('Failed to find WSL interface details') return [{ 'ip': str(interface), 'prefixlen': interface.network.prefixlen, 'gateway': gateway, }]
def run(self, terms, variables=None, **kwargs): term_pkgs = [] for term in terms: if isinstance(term, dict): paths = term.get('from', []) distro = term.get('for', "") pkg_blacklist = term.get('pkg_blacklist', []) var_blacklist = term.get('var_blacklist', []) else: raise AnsibleLookupError("Lookup item should be a dict") if not distro: raise AnsibleLookupError("Distro (for:) cannot be empty") if not paths: raise AnsibleLookupError("Locations (from:) cannot be empty") term_pkgs.extend( get_package_list(distro, paths, var_blacklist, pkg_blacklist)) return term_pkgs
def _run(self, args, expected_rc=0, command_input=None, ignore_errors=False): command = [self.cli_path] + args p = Popen(command, stdout=PIPE, stderr=PIPE, stdin=PIPE) out, err = p.communicate(input=command_input) rc = p.wait() if not ignore_errors and rc != expected_rc: raise AnsibleLookupError(to_text(err)) return rc, out, err
def assert_logged_in(self): try: rc, out, err = self._run(['get', 'account'], ignore_errors=True) if rc != 1: self._logged_in = True if not self._logged_in: self.get_token() except OSError as e: if e.errno == errno.ENOENT: raise AnsibleLookupError( "1Password CLI tool not installed in path on control machine" ) raise e except AnsibleLookupError: raise AnsibleLookupError( "Not logged into 1Password: please run 'op signin' first, or provide both subdomain and vault_password." )
def get_token(self): if not self._subdomain and not self._vault_password: raise AnsibleLookupError( 'Both subdomain and password are required when logging in.') args = ['signin', self._subdomain, '--output=raw'] rc, out, err = self._run(args, command_input=to_bytes(self._vault_password)) self._token = out.strip()
def ensure_result(result, object_type, object_name=None): if not result or object_name and object_name not in result[0].values(): return "" def _filter_result(result): return [obj for obj in result if "%2f" not in obj["name"]] result = _filter_result(result) if result and len(result) > 1: raise AnsibleLookupError( "More than one object available: [%s]." % ", ".join( list(f"{item['name']} => {item[object_type]}" for item in result))) try: object_moid = result[0][object_type] except (TypeError, KeyError, IndexError) as e: raise AnsibleLookupError(to_native(e)) return object_moid
def run(self, terms, variables=None, **kwargs): if isinstance(terms, basestring): terms = [terms] bucket_name = terms[0] conn = S3Connection(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY) bucket = conn.lookup(bucket_name) if bucket is None: raise AnsibleLookupError("Bucket %s not found" % bucket_name) return [bucket_name.encode('utf-8')]
def _get_global_config(config): try: result = getattr(C, config) if callable(result): raise AnsibleLookupError('Invalid setting "%s" attempted' % config) except AttributeError as e: raise MissingSetting(to_native(e), orig_exc=e) return result
def login(self, client_id, client_secret): display.vvv('Bitwarden login with client_id {}'.format(client_id)) bw_env = self.make_bw_env(BW_CLIENTID=client_id, BW_CLIENTSECRET=client_secret) bw_cmd = subprocess.run( [self.bw_cli, 'login', '--apikey'], capture_output = True, env = bw_env, ) if bw_cmd.returncode != 0: raise AnsibleLookupError("Bitwarden login failed: " + bw_cmd.stderr.decode('utf-8'))
def run(self, repos, variables=None, **kwargs): # lookups in general are expected to both take a list as input and output a list # this is done so they work with the looping construct 'with_'. versions = [] if len(repos) == 0: raise AnsibleParserError("You must specify at least one repo name") for repo in repos: # https://regex101.com/r/CHm7eZ/1 valid_github_username_and_repo_name = regex_compile(r"[a-z\d\-]+\/[a-z\d\S]+") if not repo or not valid_github_username_and_repo_name.match(repo): # The Parser error indicates invalid options passed raise AnsibleParserError("repo name is incorrectly formatted: %s" % to_text(repo)) display.debug("Github version lookup term: '%s'" % to_text(repo)) # Retrieve the Github API Releases JSON try: # ansible.module_utils.urls appears to handle the request errors for us response = open_url( "https://api.github.com/repos/%s/releases/latest" % repo, headers={"Accept": "application/vnd.github.v3+json"}, ) json_response = loads(response.read().decode("utf-8")) version = json_response.get("tag_name") if version is not None and len(version) != 0: versions.append(version) else: raise AnsibleLookupError( "Error extracting version from Github API response:\n%s" % to_text(response.text) ) except JSONDecodeError as e: raise AnsibleLookupError( "Error parsing JSON from Github API response: %s" % to_native(e) ) display.vvvv(u"Github version lookup using %s as repo" % to_text(repo)) return versions
def run(self, terms, variables=None, **kwargs): self.set_options(var_options=variables, direct=kwargs) rstrip = self.get_option('rstrip') use_base64 = self.get_option('base64') input_type = self.get_option('input_type') output_type = self.get_option('output_type') empty_on_not_exist = self.get_option('empty_on_not_exist') ret = [] def get_option_value(argument_name): return self.get_option(argument_name) for term in terms: display.debug("Sops lookup term: %s" % term) lookupfile = self.find_file_in_search_path( variables, 'files', term, ignore_missing=empty_on_not_exist) display.vvvv(u"Sops lookup using %s as file" % lookupfile) if not lookupfile: if empty_on_not_exist: ret.append('') continue raise AnsibleLookupError( "could not locate file in lookup: %s" % to_native(term)) try: output = Sops.decrypt(lookupfile, display=display, rstrip=rstrip, decode_output=not use_base64, input_type=input_type, output_type=output_type, get_option_value=get_option_value) except SopsError as e: raise AnsibleLookupError(to_native(e)) if use_base64: output = to_native(base64.b64encode(output)) ret.append(output) return ret