Add inventory cache to the netbox plugin (#57644)

* Add cache to netbox inventory plugin

* add changelog fragment
This commit is contained in:
Sander Steffann 2019-10-17 21:18:07 +02:00 committed by ansibot
parent 8d0737edf0
commit faf8fc62cb
2 changed files with 47 additions and 12 deletions

View file

@ -0,0 +1,2 @@
minor_changes:
- netbox - use inventory cache if configured

View file

@ -12,11 +12,13 @@ DOCUMENTATION = '''
- Remy Leone (@sieben) - Remy Leone (@sieben)
- Anthony Ruhier (@Anthony25) - Anthony Ruhier (@Anthony25)
- Nikhil Singh Baliyan (@nikkytub) - Nikhil Singh Baliyan (@nikkytub)
- Sander Steffann (@steffann)
short_description: NetBox inventory source short_description: NetBox inventory source
description: description:
- Get inventory hosts from NetBox - Get inventory hosts from NetBox
extends_documentation_fragment: extends_documentation_fragment:
- constructed - constructed
- inventory_cache
options: options:
plugin: plugin:
description: token that ensures this is a source file for the 'netbox' plugin. description: token that ensures this is a source file for the 'netbox' plugin.
@ -118,12 +120,12 @@ from sys import version as python_version
from threading import Thread from threading import Thread
from itertools import chain from itertools import chain
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable
from ansible.module_utils.ansible_release import __version__ as ansible_version from ansible.module_utils.ansible_release import __version__ as ansible_version
from ansible.errors import AnsibleError from ansible.errors import AnsibleError
from ansible.module_utils._text import to_text from ansible.module_utils._text import to_text
from ansible.module_utils.urls import open_url from ansible.module_utils.urls import open_url
from ansible.module_utils.six.moves.urllib.parse import urljoin, urlencode from ansible.module_utils.six.moves.urllib.parse import urlencode
from ansible.module_utils.compat.ipaddress import ip_interface from ansible.module_utils.compat.ipaddress import ip_interface
ALLOWED_DEVICE_QUERY_PARAMETERS = ( ALLOWED_DEVICE_QUERY_PARAMETERS = (
@ -158,21 +160,51 @@ ALLOWED_DEVICE_QUERY_PARAMETERS = (
) )
class InventoryModule(BaseInventoryPlugin, Constructable): class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
NAME = 'netbox' NAME = 'netbox'
def _fetch_information(self, url): def _fetch_information(self, url):
response = open_url(url, headers=self.headers, timeout=self.timeout, validate_certs=self.validate_certs) results = None
cache_key = self.get_cache_key(url)
try: # get the user's cache option to see if we should save the cache if it is changing
raw_data = to_text(response.read(), errors='surrogate_or_strict') user_cache_setting = self.get_option('cache')
except UnicodeError:
raise AnsibleError("Incorrect encoding of fetched payload from NetBox API.")
try: # read if the user has caching enabled and the cache isn't being refreshed
return json.loads(raw_data) attempt_to_read_cache = user_cache_setting and self.use_cache
except ValueError:
raise AnsibleError("Incorrect JSON payload: %s" % raw_data) # attempt to read the cache if inventory isn't being refreshed and the user has caching enabled
if attempt_to_read_cache:
try:
results = self._cache[cache_key]
need_to_fetch = False
except KeyError:
# occurs if the cache_key is not in the cache or if the cache_key expired
# we need to fetch the URL now
need_to_fetch = True
else:
# not reading from cache so do fetch
need_to_fetch = True
if need_to_fetch:
self.display.v("Fetching: " + url)
response = open_url(url, headers=self.headers, timeout=self.timeout, validate_certs=self.validate_certs)
try:
raw_data = to_text(response.read(), errors='surrogate_or_strict')
except UnicodeError:
raise AnsibleError("Incorrect encoding of fetched payload from NetBox API.")
try:
results = json.loads(raw_data)
except ValueError:
raise AnsibleError("Incorrect JSON payload: %s" % raw_data)
# put result in cache if enabled
if user_cache_setting:
self._cache[cache_key] = results
return results
def get_resource_list(self, api_url): def get_resource_list(self, api_url):
"""Retrieves resource list from netbox API. """Retrieves resource list from netbox API.
@ -446,6 +478,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
def parse(self, inventory, loader, path, cache=True): def parse(self, inventory, loader, path, cache=True):
super(InventoryModule, self).parse(inventory, loader, path) super(InventoryModule, self).parse(inventory, loader, path)
self._read_config_data(path=path) self._read_config_data(path=path)
self.use_cache = cache
# Netbox access # Netbox access
token = self.get_option("token") token = self.get_option("token")