mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
Lookups: use Ansible's config manager whenever possible (#5440)
* Start using Ansible's config manager to handle options. * Docs improvements. * Fix documentation, make options actual lookup options. * The cyberarkpassword lookup does too strange things. * The onepassword lookups are converted in #4728, let's not interfere. * Improve docs. * Skip shelvefile as well. * Convert lmdb_kv. * Convert and fix credstash. * Convert manifold. * Drop chef_databag. * Convert dig. * Update examples. * Forgot the most important part. * Fix lmdb_kv docs. * Python 2.6 compatibility. * Convert AnsibleUnicode to str. * Load lookup with lookup loader. * Fix environment handling and error message checking. * Improve docs formatting.
This commit is contained in:
parent
dc66aefa40
commit
e718bd8445
17 changed files with 161 additions and 91 deletions
1
.github/workflows/docs-pr.yml
vendored
1
.github/workflows/docs-pr.yml
vendored
|
@ -26,6 +26,7 @@ jobs:
|
|||
init-fail-on-error: true
|
||||
provide-link-targets: |
|
||||
ansible_collections.ansible.builtin.dict2items_filter
|
||||
ansible_collections.ansible.builtin.items_lookup
|
||||
ansible_collections.ansible.builtin.path_join_filter
|
||||
ansible_collections.community.kubevirt.kubevirt_cdi_upload_module
|
||||
ansible_collections.community.kubevirt.kubevirt_inventory
|
||||
|
|
14
changelogs/fragments/lookup-options.yml
Normal file
14
changelogs/fragments/lookup-options.yml
Normal file
|
@ -0,0 +1,14 @@
|
|||
minor_changes:
|
||||
- "cartesian lookup plugin - start using Ansible's configuration manager to parse options (https://github.com/ansible-collections/community.general/pull/5440)."
|
||||
- "credstash lookup plugin - start using Ansible's configuration manager to parse options (https://github.com/ansible-collections/community.general/pull/5440)."
|
||||
- "dependent lookup plugin - start using Ansible's configuration manager to parse options (https://github.com/ansible-collections/community.general/pull/5440)."
|
||||
- "dig lookup plugin - start using Ansible's configuration manager to parse options. All documented options can now also be passed as lookup parameters (https://github.com/ansible-collections/community.general/pull/5440)."
|
||||
- "dnstxt lookup plugin - start using Ansible's configuration manager to parse options (https://github.com/ansible-collections/community.general/pull/5440)."
|
||||
- "filetree lookup plugin - start using Ansible's configuration manager to parse options (https://github.com/ansible-collections/community.general/pull/5440)."
|
||||
- "flattened lookup plugin - start using Ansible's configuration manager to parse options (https://github.com/ansible-collections/community.general/pull/5440)."
|
||||
- "hiera lookup plugin - start using Ansible's configuration manager to parse options. The Hiera executable and config file can now also be passed as lookup parameters (https://github.com/ansible-collections/community.general/pull/5440)."
|
||||
- "keyring lookup plugin - start using Ansible's configuration manager to parse options (https://github.com/ansible-collections/community.general/pull/5440)."
|
||||
- "lmdb_kv lookup plugin - start using Ansible's configuration manager to parse options (https://github.com/ansible-collections/community.general/pull/5440)."
|
||||
- "manifold lookup plugin - start using Ansible's configuration manager to parse options (https://github.com/ansible-collections/community.general/pull/5440)."
|
||||
bugfixes:
|
||||
- "credstash lookup plugin - pass plugin options to credstash for all terms, not just for the first (https://github.com/ansible-collections/community.general/pull/5440)."
|
|
@ -15,9 +15,11 @@ DOCUMENTATION = '''
|
|||
- It is clearer with an example, it turns [1, 2, 3], [a, b] into [1, a], [1, b], [2, a], [2, b], [3, a], [3, b].
|
||||
You can see the exact syntax in the examples section.
|
||||
options:
|
||||
_raw:
|
||||
_terms:
|
||||
description:
|
||||
- a set of lists
|
||||
type: list
|
||||
elements: list
|
||||
required: true
|
||||
'''
|
||||
|
||||
|
@ -69,6 +71,7 @@ class LookupModule(LookupBase):
|
|||
return results
|
||||
|
||||
def run(self, terms, variables=None, **kwargs):
|
||||
self.set_options(var_options=variables, direct=kwargs)
|
||||
|
||||
terms = self._lookup_variables(terms)
|
||||
|
||||
|
|
|
@ -22,25 +22,33 @@ DOCUMENTATION = '''
|
|||
required: true
|
||||
table:
|
||||
description: name of the credstash table to query
|
||||
type: str
|
||||
default: 'credential-store'
|
||||
version:
|
||||
description: Credstash version
|
||||
type: str
|
||||
default: ''
|
||||
region:
|
||||
description: AWS region
|
||||
type: str
|
||||
profile_name:
|
||||
description: AWS profile to use for authentication
|
||||
type: str
|
||||
env:
|
||||
- name: AWS_PROFILE
|
||||
aws_access_key_id:
|
||||
description: AWS access key ID
|
||||
type: str
|
||||
env:
|
||||
- name: AWS_ACCESS_KEY_ID
|
||||
aws_secret_access_key:
|
||||
description: AWS access key
|
||||
type: str
|
||||
env:
|
||||
- name: AWS_SECRET_ACCESS_KEY
|
||||
aws_session_token:
|
||||
description: AWS session token
|
||||
type: str
|
||||
env:
|
||||
- name: AWS_SESSION_TOKEN
|
||||
'''
|
||||
|
@ -100,28 +108,39 @@ except ImportError:
|
|||
|
||||
|
||||
class LookupModule(LookupBase):
|
||||
def run(self, terms, variables, **kwargs):
|
||||
|
||||
def run(self, terms, variables=None, **kwargs):
|
||||
if not CREDSTASH_INSTALLED:
|
||||
raise AnsibleError('The credstash lookup plugin requires credstash to be installed.')
|
||||
|
||||
self.set_options(var_options=variables, direct=kwargs)
|
||||
|
||||
version = self.get_option('version')
|
||||
region = self.get_option('region')
|
||||
table = self.get_option('table')
|
||||
profile_name = self.get_option('profile_name')
|
||||
aws_access_key_id = self.get_option('aws_access_key_id')
|
||||
aws_secret_access_key = self.get_option('aws_secret_access_key')
|
||||
aws_session_token = self.get_option('aws_session_token')
|
||||
|
||||
context = dict(
|
||||
(k, v) for k, v in kwargs.items()
|
||||
if k not in ('version', 'region', 'table', 'profile_name', 'aws_access_key_id', 'aws_secret_access_key', 'aws_session_token')
|
||||
)
|
||||
|
||||
kwargs_pass = {
|
||||
'profile_name': profile_name,
|
||||
'aws_access_key_id': aws_access_key_id,
|
||||
'aws_secret_access_key': aws_secret_access_key,
|
||||
'aws_session_token': aws_session_token,
|
||||
}
|
||||
|
||||
ret = []
|
||||
for term in terms:
|
||||
try:
|
||||
version = kwargs.pop('version', '')
|
||||
region = kwargs.pop('region', None)
|
||||
table = kwargs.pop('table', 'credential-store')
|
||||
profile_name = kwargs.pop('profile_name', os.getenv('AWS_PROFILE', None))
|
||||
aws_access_key_id = kwargs.pop('aws_access_key_id', os.getenv('AWS_ACCESS_KEY_ID', None))
|
||||
aws_secret_access_key = kwargs.pop('aws_secret_access_key', os.getenv('AWS_SECRET_ACCESS_KEY', None))
|
||||
aws_session_token = kwargs.pop('aws_session_token', os.getenv('AWS_SESSION_TOKEN', None))
|
||||
kwargs_pass = {'profile_name': profile_name, 'aws_access_key_id': aws_access_key_id,
|
||||
'aws_secret_access_key': aws_secret_access_key, 'aws_session_token': aws_session_token}
|
||||
val = credstash.getSecret(term, version, region, table, context=kwargs, **kwargs_pass)
|
||||
ret.append(credstash.getSecret(term, version, region, table, context=context, **kwargs_pass))
|
||||
except credstash.ItemNotFound:
|
||||
raise AnsibleError('Key {0} not found'.format(term))
|
||||
except Exception as e:
|
||||
raise AnsibleError('Encountered exception while fetching {0}: {1}'.format(term, e))
|
||||
ret.append(val)
|
||||
|
||||
return ret
|
||||
|
|
|
@ -174,7 +174,6 @@ class LookupModule(LookupBase):
|
|||
"""
|
||||
|
||||
def run(self, terms, variables=None, **kwargs):
|
||||
|
||||
display.vvvv("%s" % terms)
|
||||
if isinstance(terms, list):
|
||||
return_values = []
|
||||
|
|
|
@ -16,7 +16,7 @@ description:
|
|||
or template expressions which evaluate to lists or dicts, composed of the elements of
|
||||
the input evaluated lists and dictionaries."
|
||||
options:
|
||||
_raw:
|
||||
_terms:
|
||||
description:
|
||||
- A list where the elements are one-element dictionaries, mapping a name to a string, list, or dictionary.
|
||||
The name is the index that is used in the result object. The value is iterated over as described below.
|
||||
|
@ -180,6 +180,8 @@ class LookupModule(LookupBase):
|
|||
|
||||
def run(self, terms, variables=None, **kwargs):
|
||||
"""Generate list."""
|
||||
self.set_options(var_options=variables, direct=kwargs)
|
||||
|
||||
result = []
|
||||
if len(terms) > 0:
|
||||
templar = Templar(loader=self._templar._loader)
|
||||
|
|
|
@ -21,22 +21,26 @@ DOCUMENTATION = '''
|
|||
- In addition to (default) A record, it is also possible to specify a different record type that should be queried.
|
||||
This can be done by either passing-in additional parameter of format qtype=TYPE to the dig lookup, or by appending /TYPE to the FQDN being queried.
|
||||
- If multiple values are associated with the requested record, the results will be returned as a comma-separated list.
|
||||
In such cases you may want to pass option wantlist=True to the plugin, which will result in the record values being returned as a list
|
||||
over which you can iterate later on.
|
||||
In such cases you may want to pass option I(wantlist=true) to the lookup call, or alternatively use C(query) instead of C(lookup),
|
||||
which will result in the record values being returned as a list over which you can iterate later on.
|
||||
- By default, the lookup will rely on system-wide configured DNS servers for performing the query.
|
||||
It is also possible to explicitly specify DNS servers to query using the @DNS_SERVER_1,DNS_SERVER_2,...,DNS_SERVER_N notation.
|
||||
This needs to be passed-in as an additional parameter to the lookup
|
||||
options:
|
||||
_terms:
|
||||
description: Domain(s) to query.
|
||||
type: list
|
||||
elements: str
|
||||
qtype:
|
||||
description:
|
||||
- Record type to query.
|
||||
- C(DLV) has been removed in community.general 6.0.0.
|
||||
type: str
|
||||
default: 'A'
|
||||
choices: [A, ALL, AAAA, CNAME, DNAME, DNSKEY, DS, HINFO, LOC, MX, NAPTR, NS, NSEC3PARAM, PTR, RP, RRSIG, SOA, SPF, SRV, SSHFP, TLSA, TXT]
|
||||
flat:
|
||||
description: If 0 each record is returned as a dictionary, otherwise a string.
|
||||
type: int
|
||||
default: 1
|
||||
retry_servfail:
|
||||
description: Retry a nameserver if it returns SERVFAIL.
|
||||
|
@ -59,6 +63,11 @@ DOCUMENTATION = '''
|
|||
default: false
|
||||
type: bool
|
||||
version_added: 6.0.0
|
||||
class:
|
||||
description:
|
||||
- "Class."
|
||||
type: str
|
||||
default: 'IN'
|
||||
notes:
|
||||
- ALL is not a record per-se, merely the listed fields are available for any record results you retrieve in the form of a dictionary.
|
||||
- While the 'dig' lookup plugin supports anything which dnspython supports out of the box, only a subset can be converted into a dictionary.
|
||||
|
@ -74,7 +83,7 @@ EXAMPLES = """
|
|||
|
||||
- name: "The TXT record for example.org."
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ lookup('community.general.dig', 'example.org.', 'qtype=TXT') }}"
|
||||
msg: "{{ lookup('community.general.dig', 'example.org.', qtype='TXT') }}"
|
||||
|
||||
- name: "The TXT record for example.org, alternative syntax."
|
||||
ansible.builtin.debug:
|
||||
|
@ -83,24 +92,24 @@ EXAMPLES = """
|
|||
- name: use in a loop
|
||||
ansible.builtin.debug:
|
||||
msg: "MX record for gmail.com {{ item }}"
|
||||
with_items: "{{ lookup('community.general.dig', 'gmail.com./MX', wantlist=True) }}"
|
||||
with_items: "{{ lookup('community.general.dig', 'gmail.com./MX', wantlist=true) }}"
|
||||
|
||||
- ansible.builtin.debug:
|
||||
msg: "Reverse DNS for 192.0.2.5 is {{ lookup('community.general.dig', '192.0.2.5/PTR') }}"
|
||||
- ansible.builtin.debug:
|
||||
msg: "Reverse DNS for 192.0.2.5 is {{ lookup('community.general.dig', '5.2.0.192.in-addr.arpa./PTR') }}"
|
||||
- ansible.builtin.debug:
|
||||
msg: "Reverse DNS for 192.0.2.5 is {{ lookup('community.general.dig', '5.2.0.192.in-addr.arpa.', 'qtype=PTR') }}"
|
||||
msg: "Reverse DNS for 192.0.2.5 is {{ lookup('community.general.dig', '5.2.0.192.in-addr.arpa.', qtype='PTR') }}"
|
||||
- ansible.builtin.debug:
|
||||
msg: "Querying 198.51.100.23 for IPv4 address for example.com. produces {{ lookup('dig', 'example.com', '@198.51.100.23') }}"
|
||||
|
||||
- ansible.builtin.debug:
|
||||
msg: "XMPP service for gmail.com. is available at {{ item.target }} on port {{ item.port }}"
|
||||
with_items: "{{ lookup('community.general.dig', '_xmpp-server._tcp.gmail.com./SRV', 'flat=0', wantlist=True) }}"
|
||||
with_items: "{{ lookup('community.general.dig', '_xmpp-server._tcp.gmail.com./SRV', flat=0, wantlist=true) }}"
|
||||
|
||||
- name: Retry nameservers that return SERVFAIL
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ lookup('community.general.dig', 'example.org./A', 'retry_servfail=True') }}"
|
||||
msg: "{{ lookup('community.general.dig', 'example.org./A', retry_servfail=true) }}"
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
|
@ -279,21 +288,26 @@ class LookupModule(LookupBase):
|
|||
|
||||
... flat=0 # returns a dict; default is 1 == string
|
||||
'''
|
||||
|
||||
if HAVE_DNS is False:
|
||||
raise AnsibleError("The dig lookup requires the python 'dnspython' library and it is not installed")
|
||||
|
||||
self.set_options(var_options=variables, direct=kwargs)
|
||||
|
||||
# Create Resolver object so that we can set NS if necessary
|
||||
myres = dns.resolver.Resolver(configure=True)
|
||||
edns_size = 4096
|
||||
myres.use_edns(0, ednsflags=dns.flags.DO, payload=edns_size)
|
||||
|
||||
domain = None
|
||||
qtype = 'A'
|
||||
flat = True
|
||||
fail_on_error = False
|
||||
real_empty = False
|
||||
rdclass = dns.rdataclass.from_text('IN')
|
||||
qtype = self.get_option('qtype')
|
||||
flat = self.get_option('flat')
|
||||
fail_on_error = self.get_option('fail_on_error')
|
||||
real_empty = self.get_option('real_empty')
|
||||
try:
|
||||
rdclass = dns.rdataclass.from_text(self.get_option('class'))
|
||||
except Exception as e:
|
||||
raise AnsibleError("dns lookup illegal CLASS: %s" % to_native(e))
|
||||
myres.retry_servfail = self.get_option('retry_servfail')
|
||||
|
||||
for t in terms:
|
||||
if t.startswith('@'): # e.g. "@10.0.1.2,192.0.2.1" is ok.
|
||||
|
@ -316,7 +330,7 @@ class LookupModule(LookupBase):
|
|||
continue
|
||||
if '=' in t:
|
||||
try:
|
||||
opt, arg = t.split('=')
|
||||
opt, arg = t.split('=', 1)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
|
|
@ -71,6 +71,7 @@ from ansible.plugins.lookup import LookupBase
|
|||
class LookupModule(LookupBase):
|
||||
|
||||
def run(self, terms, variables=None, **kwargs):
|
||||
self.set_options(var_options=variables, direct=kwargs)
|
||||
|
||||
if HAVE_DNS is False:
|
||||
raise AnsibleError("Can't LOOKUP(dnstxt): module dns.resolver is not installed")
|
||||
|
|
|
@ -201,6 +201,8 @@ def file_props(root, path):
|
|||
class LookupModule(LookupBase):
|
||||
|
||||
def run(self, terms, variables=None, **kwargs):
|
||||
self.set_options(var_options=variables, direct=kwargs)
|
||||
|
||||
basedir = self.get_basedir(variables)
|
||||
|
||||
ret = []
|
||||
|
|
|
@ -11,14 +11,17 @@ DOCUMENTATION = '''
|
|||
author: Serge van Ginderachter (!UNKNOWN) <serge@vanginderachter.be>
|
||||
short_description: return single list completely flattened
|
||||
description:
|
||||
- given one or more lists, this lookup will flatten any list elements found recursively until only 1 list is left.
|
||||
- Given one or more lists, this lookup will flatten any list elements found recursively until only 1 list is left.
|
||||
options:
|
||||
_terms:
|
||||
description: lists to flatten
|
||||
type: list
|
||||
elements: raw
|
||||
required: true
|
||||
notes:
|
||||
- unlike 'items' which only flattens 1 level, this plugin will continue to flatten until it cannot find lists anymore.
|
||||
- aka highlander plugin, there can only be one (list).
|
||||
- Unlike the R(items lookup,ansible_collections.ansible.builtin.items_lookup) which only flattens 1 level,
|
||||
this plugin will continue to flatten until it cannot find lists anymore.
|
||||
- Aka highlander plugin, there can only be one (list).
|
||||
'''
|
||||
|
||||
EXAMPLES = """
|
||||
|
@ -78,9 +81,10 @@ class LookupModule(LookupBase):
|
|||
|
||||
return ret
|
||||
|
||||
def run(self, terms, variables, **kwargs):
|
||||
|
||||
def run(self, terms, variables=None, **kwargs):
|
||||
if not isinstance(terms, list):
|
||||
raise AnsibleError("with_flattened expects a list")
|
||||
|
||||
self.set_options(var_options=variables, direct=kwargs)
|
||||
|
||||
return self._do_flatten(terms, variables)
|
||||
|
|
|
@ -14,23 +14,23 @@ DOCUMENTATION = '''
|
|||
requirements:
|
||||
- hiera (command line utility)
|
||||
description:
|
||||
- Retrieves data from an Puppetmaster node using Hiera as ENC
|
||||
- Retrieves data from an Puppetmaster node using Hiera as ENC.
|
||||
options:
|
||||
_hiera_key:
|
||||
_terms:
|
||||
description:
|
||||
- The list of keys to lookup on the Puppetmaster
|
||||
- The list of keys to lookup on the Puppetmaster.
|
||||
type: list
|
||||
elements: string
|
||||
required: true
|
||||
_bin_file:
|
||||
executable:
|
||||
description:
|
||||
- Binary file to execute Hiera
|
||||
- Binary file to execute Hiera.
|
||||
default: '/usr/bin/hiera'
|
||||
env:
|
||||
- name: ANSIBLE_HIERA_BIN
|
||||
_hierarchy_file:
|
||||
config_file:
|
||||
description:
|
||||
- File that describes the hierarchy of Hiera
|
||||
- File that describes the hierarchy of Hiera.
|
||||
default: '/etc/hiera.yaml'
|
||||
env:
|
||||
- name: ANSIBLE_HIERA_CFG
|
||||
|
@ -67,25 +67,28 @@ from ansible.plugins.lookup import LookupBase
|
|||
from ansible.utils.cmd_functions import run_cmd
|
||||
from ansible.module_utils.common.text.converters import to_text
|
||||
|
||||
ANSIBLE_HIERA_CFG = os.getenv('ANSIBLE_HIERA_CFG', '/etc/hiera.yaml')
|
||||
ANSIBLE_HIERA_BIN = os.getenv('ANSIBLE_HIERA_BIN', '/usr/bin/hiera')
|
||||
|
||||
|
||||
class Hiera(object):
|
||||
def __init__(self, hiera_cfg, hiera_bin):
|
||||
self.hiera_cfg = hiera_cfg
|
||||
self.hiera_bin = hiera_bin
|
||||
|
||||
def get(self, hiera_key):
|
||||
pargs = [ANSIBLE_HIERA_BIN]
|
||||
pargs.extend(['-c', ANSIBLE_HIERA_CFG])
|
||||
pargs = [self.hiera_bin]
|
||||
pargs.extend(['-c', self.hiera_cfg])
|
||||
|
||||
pargs.extend(hiera_key)
|
||||
|
||||
rc, output, err = run_cmd("{0} -c {1} {2}".format(
|
||||
ANSIBLE_HIERA_BIN, ANSIBLE_HIERA_CFG, hiera_key[0]))
|
||||
self.hiera_bin, self.hiera_cfg, hiera_key[0]))
|
||||
|
||||
return to_text(output.strip())
|
||||
|
||||
|
||||
class LookupModule(LookupBase):
|
||||
def run(self, terms, variables=''):
|
||||
hiera = Hiera()
|
||||
def run(self, terms, variables=None, **kwargs):
|
||||
self.set_options(var_options=variables, direct=kwargs)
|
||||
|
||||
hiera = Hiera(self.get_option('config_file'), self.get_option('executable'))
|
||||
ret = [hiera.get(terms)]
|
||||
return ret
|
||||
|
|
|
@ -26,7 +26,9 @@ EXAMPLES = """
|
|||
- 'servicename username'
|
||||
|
||||
- name: access mysql with password from keyring
|
||||
mysql_db: login_password={{lookup('community.general.keyring','mysql joe')}} login_user=joe
|
||||
community.mysql.mysql_db:
|
||||
login_password: "{{ lookup('community.general.keyring', 'mysql joe') }}"
|
||||
login_user: joe
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
|
@ -53,10 +55,12 @@ display = Display()
|
|||
|
||||
class LookupModule(LookupBase):
|
||||
|
||||
def run(self, terms, **kwargs):
|
||||
def run(self, terms, variables=None, **kwargs):
|
||||
if not HAS_KEYRING:
|
||||
raise AnsibleError(u"Can't LOOKUP(keyring): missing required python library 'keyring'")
|
||||
|
||||
self.set_options(var_options=variables, direct=kwargs)
|
||||
|
||||
display.vvvv(u"keyring: %s" % keyring.get_keyring())
|
||||
ret = []
|
||||
for term in terms:
|
||||
|
|
|
@ -13,15 +13,20 @@ DOCUMENTATION = '''
|
|||
version_added: '0.2.0'
|
||||
short_description: fetch data from LMDB
|
||||
description:
|
||||
- This lookup returns a list of results from an LMDB DB corresponding to a list of items given to it
|
||||
- This lookup returns a list of results from an LMDB DB corresponding to a list of items given to it.
|
||||
requirements:
|
||||
- lmdb (python library https://lmdb.readthedocs.io/en/release/)
|
||||
options:
|
||||
_terms:
|
||||
description: list of keys to query
|
||||
description: List of keys to query.
|
||||
type: list
|
||||
elements: str
|
||||
db:
|
||||
description: path to LMDB database
|
||||
description: Path to LMDB database.
|
||||
type: str
|
||||
default: 'ansible.mdb'
|
||||
vars:
|
||||
- name: lmdb_kv_db
|
||||
'''
|
||||
|
||||
EXAMPLES = """
|
||||
|
@ -58,6 +63,7 @@ _raw:
|
|||
from ansible.errors import AnsibleError
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
from ansible.module_utils.common.text.converters import to_native, to_text
|
||||
|
||||
HAVE_LMDB = True
|
||||
try:
|
||||
import lmdb
|
||||
|
@ -67,8 +73,7 @@ except ImportError:
|
|||
|
||||
class LookupModule(LookupBase):
|
||||
|
||||
def run(self, terms, variables, **kwargs):
|
||||
|
||||
def run(self, terms, variables=None, **kwargs):
|
||||
'''
|
||||
terms contain any number of keys to be retrieved.
|
||||
If terms is None, all keys from the database are returned
|
||||
|
@ -81,17 +86,15 @@ class LookupModule(LookupBase):
|
|||
vars:
|
||||
- lmdb_kv_db: "jp.mdb"
|
||||
'''
|
||||
|
||||
if HAVE_LMDB is False:
|
||||
raise AnsibleError("Can't LOOKUP(lmdb_kv): this module requires lmdb to be installed")
|
||||
|
||||
db = variables.get('lmdb_kv_db', None)
|
||||
if db is None:
|
||||
db = kwargs.get('db', 'ansible.mdb')
|
||||
db = str(db)
|
||||
self.set_options(var_options=variables, direct=kwargs)
|
||||
|
||||
db = self.get_option('db')
|
||||
|
||||
try:
|
||||
env = lmdb.open(db, readonly=True)
|
||||
env = lmdb.open(str(db), readonly=True)
|
||||
except Exception as e:
|
||||
raise AnsibleError("LMDB can't open database %s: %s" % (db, to_native(e)))
|
||||
|
||||
|
|
|
@ -207,7 +207,7 @@ class ManifoldApiClient(object):
|
|||
|
||||
class LookupModule(LookupBase):
|
||||
|
||||
def run(self, terms, variables=None, api_token=None, project=None, team=None):
|
||||
def run(self, terms, variables=None, **kwargs):
|
||||
"""
|
||||
:param terms: a list of resources lookups to run.
|
||||
:param variables: ansible variables active at the time of the lookup
|
||||
|
@ -217,10 +217,11 @@ class LookupModule(LookupBase):
|
|||
:return: a dictionary of resources credentials
|
||||
"""
|
||||
|
||||
if not api_token:
|
||||
api_token = os.getenv('MANIFOLD_API_TOKEN')
|
||||
if not api_token:
|
||||
raise AnsibleError('API token is required. Please set api_token parameter or MANIFOLD_API_TOKEN env var')
|
||||
self.set_options(var_options=variables, direct=kwargs)
|
||||
|
||||
api_token = self.get_option('api_token')
|
||||
project = self.get_option('project')
|
||||
team = self.get_option('team')
|
||||
|
||||
try:
|
||||
labels = terms
|
||||
|
|
|
@ -14,23 +14,24 @@ DOCUMENTATION = '''
|
|||
- Read keys from Python shelve file.
|
||||
options:
|
||||
_terms:
|
||||
description: sets of key value pairs of parameters
|
||||
description: Sets of key value pairs of parameters.
|
||||
key:
|
||||
description: key to query
|
||||
description: Key to query.
|
||||
required: true
|
||||
file:
|
||||
description: path to shelve file
|
||||
description: Path to shelve file.
|
||||
required: true
|
||||
'''
|
||||
|
||||
EXAMPLES = """
|
||||
- name: retrieve a string value corresponding to a key inside a Python shelve file
|
||||
ansible.builtin.debug: msg="{{ lookup('community.general.shelvefile', 'file=path_to_some_shelve_file.db key=key_to_retrieve') }}
|
||||
- name: Retrieve a string value corresponding to a key inside a Python shelve file
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ lookup('community.general.shelvefile', 'file=path_to_some_shelve_file.db key=key_to_retrieve') }}"
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
_list:
|
||||
description: value(s) of key(s) in shelve file(s)
|
||||
description: Value(s) of key(s) in shelve file(s).
|
||||
type: list
|
||||
elements: str
|
||||
"""
|
||||
|
@ -53,7 +54,6 @@ class LookupModule(LookupBase):
|
|||
return res
|
||||
|
||||
def run(self, terms, variables=None, **kwargs):
|
||||
|
||||
if not isinstance(terms, list):
|
||||
terms = [terms]
|
||||
|
||||
|
|
|
@ -6,10 +6,10 @@
|
|||
- hosts: localhost
|
||||
tasks:
|
||||
- debug:
|
||||
msg: '{{ query(''community.general.lmdb_kv'', ''nl'', ''be'', ''lu'', db=''jp.mdb'') }}'
|
||||
msg: '{{ query("community.general.lmdb_kv", "nl", "be", "lu", db="jp.mdb") }}'
|
||||
- debug:
|
||||
var: item.1
|
||||
loop: '{{ query(''community.general.lmdb_kv'', db=''jp.mdb'') }}'
|
||||
loop: '{{ query("community.general.lmdb_kv", db="jp.mdb") }}'
|
||||
- assert:
|
||||
that:
|
||||
- query('community.general.lmdb_kv', 'nl', 'be', 'lu', db='jp.mdb') == ['Netherlands', 'Belgium', 'Luxembourg']
|
||||
|
|
|
@ -11,8 +11,10 @@ from ansible.errors import AnsibleError
|
|||
from ansible.module_utils.urls import ConnectionError, SSLValidationError
|
||||
from ansible.module_utils.six.moves.urllib.error import HTTPError, URLError
|
||||
from ansible.module_utils import six
|
||||
from ansible.plugins.loader import lookup_loader
|
||||
from ansible_collections.community.general.plugins.lookup.manifold import ManifoldApiClient, LookupModule, ApiError
|
||||
import json
|
||||
import os
|
||||
|
||||
|
||||
API_FIXTURES = {
|
||||
|
@ -375,8 +377,7 @@ class TestManifoldApiClient(unittest.TestCase):
|
|||
|
||||
class TestLookupModule(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.lookup = LookupModule()
|
||||
self.lookup._load_name = "manifold"
|
||||
self.lookup = lookup_loader.get('community.general.manifold')
|
||||
|
||||
@patch('ansible_collections.community.general.plugins.lookup.manifold.ManifoldApiClient')
|
||||
def test_get_all(self, client_mock):
|
||||
|
@ -515,23 +516,22 @@ class TestLookupModule(unittest.TestCase):
|
|||
self.lookup.run([], api_token='token-123')
|
||||
self.assertTrue('Exception: Unknown error' in str(context.exception))
|
||||
|
||||
@patch('ansible_collections.community.general.plugins.lookup.manifold.os.getenv')
|
||||
@patch('ansible_collections.community.general.plugins.lookup.manifold.ManifoldApiClient')
|
||||
def test_falls_back_to_env_var(self, client_mock, getenv_mock):
|
||||
getenv_mock.return_value = 'token-321'
|
||||
def test_falls_back_to_env_var(self, client_mock):
|
||||
client_mock.return_value.get_resources.return_value = []
|
||||
client_mock.return_value.get_credentials.return_value = []
|
||||
try:
|
||||
os.environ['MANIFOLD_API_TOKEN'] = 'token-321'
|
||||
self.lookup.run([])
|
||||
getenv_mock.assert_called_with('MANIFOLD_API_TOKEN')
|
||||
finally:
|
||||
os.environ.pop('MANIFOLD_API_TOKEN', None)
|
||||
client_mock.assert_called_with('token-321')
|
||||
|
||||
@patch('ansible_collections.community.general.plugins.lookup.manifold.os.getenv')
|
||||
@patch('ansible_collections.community.general.plugins.lookup.manifold.ManifoldApiClient')
|
||||
def test_falls_raises_on_no_token(self, client_mock, getenv_mock):
|
||||
getenv_mock.return_value = None
|
||||
def test_falls_raises_on_no_token(self, client_mock):
|
||||
client_mock.return_value.get_resources.return_value = []
|
||||
client_mock.return_value.get_credentials.return_value = []
|
||||
os.environ.pop('MANIFOLD_API_TOKEN', None)
|
||||
with self.assertRaises(AnsibleError) as context:
|
||||
self.lookup.run([])
|
||||
self.assertEqual('API token is required. Please set api_token parameter or MANIFOLD_API_TOKEN env var',
|
||||
str(context.exception))
|
||||
assert 'api_token' in str(context.exception)
|
||||
|
|
Loading…
Reference in a new issue