From 6bca5e5a4ad7ca6120e002a00aef107c6f6be986 Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Mon, 20 Nov 2017 09:24:10 -0500 Subject: [PATCH] add lookups to config system (#33026) * add lookups to config system use etcd as proof of concept * some doc updates --- lib/ansible/plugins/loader.py | 2 +- lib/ansible/plugins/lookup/__init__.py | 11 ++++-- lib/ansible/plugins/lookup/etcd.py | 49 +++++++++++--------------- 3 files changed, 30 insertions(+), 32 deletions(-) diff --git a/lib/ansible/plugins/loader.py b/lib/ansible/plugins/loader.py index 2bca3b29f1d..211dd4c6de8 100644 --- a/lib/ansible/plugins/loader.py +++ b/lib/ansible/plugins/loader.py @@ -210,7 +210,7 @@ class PluginLoader: type_name = get_plugin_class(self.class_name) # FIXME: expand from just connection and callback - if type_name in ('callback', 'connection', 'inventory'): + if type_name in ('callback', 'connection', 'inventory', 'lookup'): dstring = read_docstring(path, verbose=False, ignore_errors=False) if dstring.get('doc', False): diff --git a/lib/ansible/plugins/lookup/__init__.py b/lib/ansible/plugins/lookup/__init__.py index 16fbfd8e046..102301d4d98 100644 --- a/lib/ansible/plugins/lookup/__init__.py +++ b/lib/ansible/plugins/lookup/__init__.py @@ -19,10 +19,10 @@ from __future__ import (absolute_import, division, print_function) __metaclass__ = type -from abc import ABCMeta, abstractmethod +from abc import abstractmethod -from ansible.module_utils.six import with_metaclass from ansible.errors import AnsibleFileNotFound +from ansible.plugins import AnsiblePlugin try: from __main__ import display @@ -33,10 +33,15 @@ except ImportError: __all__ = ['LookupBase'] -class LookupBase(with_metaclass(ABCMeta, object)): +class LookupBase(AnsiblePlugin): + def __init__(self, loader=None, templar=None, **kwargs): + + super(LookupBase, self).__init__() + self._loader = loader self._templar = templar + # Backwards compat: self._display isn't really needed, just import the global display and use that. self._display = display diff --git a/lib/ansible/plugins/lookup/etcd.py b/lib/ansible/plugins/lookup/etcd.py index 4ed7db24da6..f8eabf74e41 100644 --- a/lib/ansible/plugins/lookup/etcd.py +++ b/lib/ansible/plugins/lookup/etcd.py @@ -34,30 +34,34 @@ DOCUMENTATION = ''' type: list elements: string required: True - _etcd_url: + url: description: - Environment variable with the url for the etcd server default: 'http://127.0.0.1:4001' env: - name: ANSIBLE_ETCD_URL - yaml: - - key: etcd.url - _etcd_version: + version: description: - Environment variable with the etcd protocol version default: 'v1' env: - name: ANSIBLE_ETCD_VERSION - yaml: - - key: etcd.version + validate_certs: + description: + - toggle checking that the ssl ceritificates are valid, you normally only want to turn this off with self-signed certs. + default: True + type: boolean ''' EXAMPLES = ''' - name: "a value from a locally running etcd" debug: msg={{ lookup('etcd', 'foo/bar') }} - - name: "a values from a folder on a locally running etcd" - debug: msg={{ lookup('etcd', 'foo') }} + - name: "values from multiple folders on a locally running etcd" + debug: msg={{ lookup('etcd', 'foo', 'bar', 'baz') }} + + - name: "since Ansible 2.5 you can set server options inline" + debug: msg="{{ lookup('etcd', 'foo', version='v2', url='http://192.168.0.27:4001') }}" ''' RETURN = ''' @@ -68,12 +72,7 @@ RETURN = ''' elements: strings ''' -import os - -try: - import json -except ImportError: - import simplejson as json +import json from ansible.plugins.lookup import LookupBase from ansible.module_utils.urls import open_url @@ -102,18 +101,10 @@ from ansible.module_utils.urls import open_url # # # -ANSIBLE_ETCD_URL = 'http://127.0.0.1:4001' -if os.getenv('ANSIBLE_ETCD_URL') is not None: - ANSIBLE_ETCD_URL = os.environ['ANSIBLE_ETCD_URL'] - -ANSIBLE_ETCD_VERSION = 'v1' -if os.getenv('ANSIBLE_ETCD_VERSION') is not None: - ANSIBLE_ETCD_VERSION = os.environ['ANSIBLE_ETCD_VERSION'] class Etcd: - def __init__(self, url=ANSIBLE_ETCD_URL, version=ANSIBLE_ETCD_VERSION, - validate_certs=True): + def __init__(self, url, version, validate_certs): self.url = url self.version = version self.baseurl = '%s/%s/keys' % (self.url, self.version) @@ -143,7 +134,7 @@ class Etcd: try: r = open_url(url, validate_certs=self.validate_certs) data = r.read() - except: + except Exception: return None try: @@ -161,7 +152,7 @@ class Etcd: if 'errorCode' in item: # Here return an error when an unknown entry responds value = "ENOENT" - except: + except Exception: raise return value @@ -171,9 +162,11 @@ class LookupModule(LookupBase): def run(self, terms, variables, **kwargs): - validate_certs = kwargs.get('validate_certs', True) - url = kwargs.get('url', '') - version = kwargs.get('version', '') + self.set_options(var_options=variables, direct=kwargs) + + validate_certs = self._options['validate_certs'] + url = self._options['url'] + version = self._options['version'] etcd = Etcd(url=url, version=version, validate_certs=validate_certs)