From c0e02b29ba88fd25fe8bd8bb02d218238abecbb8 Mon Sep 17 00:00:00 2001
From: Bombar Maxime <bombar@crans.org>
Date: Sun, 3 May 2020 15:49:58 +0200
Subject: [PATCH] [re2o_lookup] Add support for json, yaml, pickle and
 memcached cache plugins.

---
 ansible.cfg               |  5 +++
 lookup_plugins/re2oapi.py | 68 ++++++++++++++++++++++++++++-----------
 2 files changed, 55 insertions(+), 18 deletions(-)

diff --git a/ansible.cfg b/ansible.cfg
index 85718531..149b1ce6 100644
--- a/ansible.cfg
+++ b/ansible.cfg
@@ -49,6 +49,11 @@ use_cpasswords = True
 # Specify cache plugin for re2o API. By default, cache nothing
 cache = jsonfile
 
+# Only used for memcached plugin
+# List of connection information for the memcached DBs
+# Default is ['127.0.0.1:11211']
+# memcached_connection = ['127.0.0.1:11211']
+
 # Time in second before the cache expired. 0 means never expire cache.
 # Default is 24 hours.
 timeout = 86400
diff --git a/lookup_plugins/re2oapi.py b/lookup_plugins/re2oapi.py
index e1f1041b..2a8b4819 100644
--- a/lookup_plugins/re2oapi.py
+++ b/lookup_plugins/re2oapi.py
@@ -374,6 +374,27 @@ class LookupModule(LookupBase):
                     return config.getint(section, key)
                 else:
                     return config.get(section, key)
+            else:
+                return default
+
+    def _manage_cachedir(self, cachedir=None, plugin=None):
+        try:
+            self._uri = cachedir / plugin
+        except Exception:
+            raise AnsibleError("Undefined specification for cache plugin")
+
+        display.vvv("Cache directory is {}".format(self._uri))
+        if not self._uri.exists():
+            # Creates Ansible cache directory with right permissions
+            # if it doesn't exist yet.
+            display.vvv("Cache directory doesn't exist. Creating it.")
+            try:
+                self._uri.mkdir(mode=0o700, parents=True)
+            except Exception as e:
+                raise AnsibleError("""Unable to create {dir}.
+                Original error was : {err}""".format(dir=self._uri,
+                                                     err=to_native(e)))
+
 
     def __init__(self, *args, **kwargs):
         super().__init__(*args, **kwargs)
@@ -410,29 +431,36 @@ class LookupModule(LookupBase):
 
         if self._cache_plugin is not None:
             display.vvv("Using {} as cache plugin".format(self._cache_plugin))
+            cachedir = Path.home() / ".cache/ansible/re2oapi"
 
             if self._cache_plugin == 'jsonfile':
-                self._cachedir = Path.home() / ".cache/Ansible/re2oapi"
-                display.vvv("Cache directory is {}".format(self._cachedir))
-                if not self._cachedir.exists():
-                    # Creates Ansible cache directory with right permissions
-                    # if it doesn't exist yet.
-                    display.vvv("Cache directory doesn't exist. Creating it.")
-                    try:
-                        self._cachedir.mkdir(mode=0o700, parents=True)
-                    except Exception as e:
-                        raise AnsibleError("""Unable to create {dir}.
-                        Original error was : {err}"""
-                                           .format(dir=self._cachedir,
-                                                   err=to_native(e)))
-                self._cache = cache_loader.get('jsonfile',
-                                               _uri=self._cachedir,
-                                               _timeout=self._timeout,
-                                               )
+                self._manage_cachedir(cachedir=cachedir, plugin='json')
+            elif self._cache_plugin == 'yaml':
+                self._manage_cachedir(cachedir=cachedir, plugin='yaml')
+            elif self._cache_plugin == 'pickle':
+                self._manage_cachedir(cachedir=cachedir, plugin='pickle')
+            elif self._cache_plugin == 'memcached':
+                # requires packages python3-memcache and memcached
+                display.vvvv("Please make sure you have installed packages"
+                             "python3-memcache and memcached"
+                             )
+                self._uri = self._readconfig(key='memcached_connection',
+                                                  default=['127.0.0.1:11211'],
+                                                  )
             else:
                 raise AnsibleError("Cache plugin {} not supported"
                                    .format(self._cache_plugin))
 
+            self._cache = cache_loader.get(self._cache_plugin,
+                                           _uri=self._uri,
+                                           _timeout=self._timeout,
+                                           )
+            self._cachetoken = cache_loader.get(self._cache_plugin,
+                                                _uri=self._uri,
+                                                _timeout=self._timeouttoken,
+                                                )
+
+
     def run(self, terms, variables=None, api_hostname=None, api_username=None,
             api_password=None, use_tls=True):
 
@@ -546,7 +574,7 @@ class LookupModule(LookupBase):
             zones_name = [zone["name"][1:] for zone in zones]
             display.vvv("Storing dnszones in cache.")
             self._set_cache('dnszones', zones_name)
-
+        display.vvv('\n')
         return zones_name
 
     def _getreverse(self, api_client):
@@ -615,6 +643,7 @@ class LookupModule(LookupBase):
             display.vvv("Storing dns reverse zones in cache.")
             self._set_cache('dnsreverse', list(set(res)))
 
+        display.vvv('\n')
         return res
 
     def _rawquery(self, api_client, endpoint):
@@ -629,6 +658,8 @@ class LookupModule(LookupBase):
             res = api_client.list(endpoint)
             display.vvv("Storing result in cache.")
             self._set_cache(endpoint.replace('/', '_'), res)
+
+        display.vvv('\n')
         return res
 
     def _get_role(self, api_client, role_name):
@@ -655,4 +686,5 @@ class LookupModule(LookupBase):
             display.vvv("Storing {} in cache.".format(role_name))
             self._set_cache(role_name, res)
 
+        display.vvv('\n')
         return res
-- 
GitLab