|
''' |
|
Kyle James Walker <[email protected]> |
|
|
|
This file is a lookup plugin for Ansible |
|
|
|
Ansible is free software: you can redistribute it and/or modify |
|
it under the terms of the GNU General Public License as published by |
|
the Free Software Foundation, either version 3 of the License, or |
|
(at your option) any later version. |
|
|
|
Ansible is distributed in the hope that it will be useful, |
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
GNU General Public License for more details. |
|
|
|
You should have received a copy of the GNU General Public License |
|
along with Ansible. If not, see <http://www.gnu.org/licenses/>. |
|
''' |
|
|
|
import traceback |
|
|
|
from ansible.utils import listify_lookup_plugin_terms |
|
from ansible.errors import AnsibleError |
|
|
|
|
|
def walk_path(root_node, path): |
|
node = root_node |
|
for p in path.split('.'): |
|
node = node[p] |
|
return node |
|
|
|
|
|
def flatten_dict_with(terms, lookup_path): |
|
ret = [] |
|
|
|
for key in terms: |
|
value = walk_path(terms[key], lookup_path) |
|
if not isinstance(value, list): |
|
raise AnsibleError("the path %s should point to a list," |
|
" got '%s'" % (lookup_path, value)) |
|
for i in value: |
|
ret.append({'key': key, |
|
'value': i, |
|
'root': terms[key]}) |
|
return ret |
|
|
|
|
|
def flatten_list_with(terms, lookup_path): |
|
ret = [] |
|
|
|
for idx, val in enumerate(terms): |
|
value = walk_path(val, lookup_path) |
|
if not isinstance(value, list): |
|
raise AnsibleError("the path %s should point to a list," |
|
" got '%s'" % (lookup_path, value)) |
|
for i in value: |
|
ret.append({'index': idx, |
|
'value': i, |
|
'root': terms[idx]}) |
|
return ret |
|
|
|
|
|
class LookupModule(object): |
|
def __init__(self, basedir=None, **kwargs): |
|
self.basedir = basedir |
|
|
|
def run(self, terms, inject=None, **kwargs): |
|
try: |
|
terms = listify_lookup_plugin_terms(terms, |
|
self.basedir, |
|
inject) |
|
|
|
if not isinstance(terms, dict) and 'path' not in terms: |
|
raise AnsibleError( |
|
"dict_subelements requires a dict with path key" |
|
) |
|
|
|
if 'dict' not in terms and 'items' not in terms: |
|
raise AnsibleError( |
|
"dict_path requires a dict with dict or items key" |
|
) |
|
|
|
if 'dict' in terms and 'items' in terms: |
|
raise AnsibleError( |
|
"dict_subelements can't have a dict and items key" |
|
) |
|
|
|
root_key = 'dict' if 'dict' in terms else 'items' |
|
root_element = listify_lookup_plugin_terms(terms[root_key], |
|
self.basedir, |
|
inject) |
|
path = terms['path'] |
|
|
|
if not isinstance(root_element, (dict, list)): |
|
raise AnsibleError("Invalid type for dict/list key") |
|
if not isinstance(path, basestring): |
|
raise AnsibleError("Invalid type for path key " |
|
"basestring required") |
|
|
|
if root_key is 'dict': |
|
return flatten_dict_with(root_element, path) |
|
else: |
|
return flatten_list_with(root_element, path) |
|
except Exception as e: |
|
problem = "{}\n{}".format(e, traceback.format_exc()) |
|
raise AnsibleError(problem) |