Add openstack logger and Ansible display utility

Story: 2007879

Change-Id: I76fc7df8202b4e00b54b5bafe7719e02b49e59ff
This commit is contained in:
Marc-Antoine Bourgeot
2020-07-07 16:21:57 +02:00
parent 94e518e42c
commit 40ce8103f4

View File

@@ -116,9 +116,14 @@ all_projects: yes
import collections import collections
import sys import sys
import logging
from ansible.errors import AnsibleParserError from ansible.errors import AnsibleParserError
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable
from ansible.utils.display import Display
display = Display()
os_logger = logging.getLogger("openstack")
try: try:
# Due to the name shadowing we should import other way # Due to the name shadowing we should import other way
@@ -126,8 +131,10 @@ try:
sdk = importlib.import_module('openstack') sdk = importlib.import_module('openstack')
sdk_inventory = importlib.import_module('openstack.cloud.inventory') sdk_inventory = importlib.import_module('openstack.cloud.inventory')
client_config = importlib.import_module('openstack.config.loader') client_config = importlib.import_module('openstack.config.loader')
sdk_exceptions = importlib.import_module("openstack.exceptions")
HAS_SDK = True HAS_SDK = True
except ImportError: except ImportError:
display.vvvv("Couldn't import Openstack SDK modules")
HAS_SDK = False HAS_SDK = False
@@ -156,11 +163,14 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
msg = "openstacksdk is required for the OpenStack inventory plugin. OpenStack inventory sources will be skipped." msg = "openstacksdk is required for the OpenStack inventory plugin. OpenStack inventory sources will be skipped."
if msg: if msg:
display.vvvv(msg)
raise AnsibleParserError(msg) raise AnsibleParserError(msg)
# The user has pointed us at a clouds.yaml file. Use defaults for
# everything.
if 'clouds' in self._config_data: if 'clouds' in self._config_data:
self.display.vvvv(
"Found clouds config file instead of plugin config. "
"Using default configuration."
)
self._config_data = {} self._config_data = {}
# update cache if the user has caching enabled and the cache is being refreshed # update cache if the user has caching enabled and the cache is being refreshed
@@ -171,13 +181,16 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
cache = self.get_option('cache') cache = self.get_option('cache')
source_data = None source_data = None
if cache: if cache:
self.display.vvvv("Reading inventory data from cache: %s" % cache_key)
try: try:
source_data = self._cache[cache_key] source_data = self._cache[cache_key]
except KeyError: except KeyError:
# cache expired or doesn't exist yet # cache expired or doesn't exist yet
display.vvvv("Inventory data cache not found")
cache_needs_update = True cache_needs_update = True
if not source_data: if not source_data:
self.display.vvvv("Getting hosts from Openstack clouds")
clouds_yaml_path = self._config_data.get('clouds_yaml_path') clouds_yaml_path = self._config_data.get('clouds_yaml_path')
if clouds_yaml_path: if clouds_yaml_path:
config_files = ( config_files = (
@@ -190,11 +203,16 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
# Redict logging to stderr so it does not mix with output # Redict logging to stderr so it does not mix with output
# particular ansible-inventory JSON output # particular ansible-inventory JSON output
# TODO(mordred) Integrate openstack's logging with ansible's logging # TODO(mordred) Integrate openstack's logging with ansible's logging
sdk.enable_logging(stream=sys.stderr) if self.display.verbosity > 3:
sdk.enable_logging(debug=True, stream=sys.stderr)
else:
sdk.enable_logging(stream=sys.stderr)
cloud_inventory = sdk_inventory.OpenStackInventory( cloud_inventory = sdk_inventory.OpenStackInventory(
config_files=config_files, config_files=config_files,
private=self._config_data.get('private', False)) private=self._config_data.get('private', False))
self.display.vvvv("Found %d cloud(s) in Openstack" %
len(cloud_inventory.clouds))
only_clouds = self._config_data.get('only_clouds', []) only_clouds = self._config_data.get('only_clouds', [])
if only_clouds and not isinstance(only_clouds, list): if only_clouds and not isinstance(only_clouds, list):
raise ValueError( raise ValueError(
@@ -203,20 +221,31 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
if only_clouds: if only_clouds:
new_clouds = [] new_clouds = []
for cloud in cloud_inventory.clouds: for cloud in cloud_inventory.clouds:
self.display.vvvv("Looking at cloud : %s" % cloud.name)
if cloud.name in only_clouds: if cloud.name in only_clouds:
self.display.vvvv("Selecting cloud : %s" % cloud.name)
new_clouds.append(cloud) new_clouds.append(cloud)
cloud_inventory.clouds = new_clouds cloud_inventory.clouds = new_clouds
self.display.vvvv("Selected %d cloud(s)" %
len(cloud_inventory.clouds))
expand_hostvars = self._config_data.get('expand_hostvars', False) expand_hostvars = self._config_data.get('expand_hostvars', False)
fail_on_errors = self._config_data.get('fail_on_errors', False) fail_on_errors = self._config_data.get('fail_on_errors', False)
all_projects = self._config_data.get('all_projects', False) all_projects = self._config_data.get('all_projects', False)
source_data = cloud_inventory.list_hosts( source_data = []
expand=expand_hostvars, fail_on_cloud_config=fail_on_errors, try:
all_projects=all_projects) source_data = cloud_inventory.list_hosts(
expand=expand_hostvars, fail_on_cloud_config=fail_on_errors,
if cache_needs_update: all_projects=all_projects)
self._cache[cache_key] = source_data except Exception as e:
self.display.warning("Couldn't list Openstack hosts. "
"See logs for details")
os_logger.error(e.message)
finally:
if cache_needs_update:
self._cache[cache_key] = source_data
self._populate_from_source(source_data) self._populate_from_source(source_data)
@@ -342,5 +371,6 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
for suffix in ('yaml', 'yml'): for suffix in ('yaml', 'yml'):
maybe = '{fn}.{suffix}'.format(fn=fn, suffix=suffix) maybe = '{fn}.{suffix}'.format(fn=fn, suffix=suffix)
if path.endswith(maybe): if path.endswith(maybe):
self.display.vvvv("Valid plugin config file found")
return True return True
return False return False