Add: Kheop inventory plugin

This commit is contained in:
Robin Pierre Cordier 2022-02-09 18:06:11 -05:00
parent 566e6c9e7d
commit 31a52f84f7

252
plugins/inventory/kheops.py Normal file
View File

@ -0,0 +1,252 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020 Robin Cordier <>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
# pylint: disable=raise-missing-from
# pylint: disable=super-with-arguments
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from pprint import pprint
DOCUMENTATION = '''
name: kheops
plugin_type: inventory
short_description: Kheops host classifier
requirements:
- requests >= 1.1
description:
- This plugin does not create hosts, but it assign new variables from Kheops to hosts
- The main usecase of this plugin is to act as a node
- Get host variables from Kheops (http://kheops.io/)
-
- This plugin get all hosts from inventory and add lookep up keys
- It's important to make this inventory source loaded after all other hosts has been declared. To force whit behavior, you can name your inventory file by `zzz_` to be sure it will be the last one to be parsed
extends_documentation_fragment:
- inventory_cache
- constructed
options:
plugin:
description: token that ensures this is a source file for the C(kheops) plugin.
required: True
choices: ['kheops', 'barbu_it.ansible_kheops.kheops']
# Query configuration
# ==========================
query_namespace:
description:
- The Kheops namespace to use
default: 'default'
env:
- name: ANSIBLE_KHEOPS_NAMESPACE
query_scope:
description:
- A hash containing the scope to use for the request, the values will be resolved as Ansible facts.
- Use a dot notation to dig deeper into nested hash facts.
default: {}
query_keys:
description:
- A list of keys to lookup
default: {}
# Instance configuration
# ==========================
configuration:
description:
- Path to Kheops configuration yaml file
default: 'kheops.yml'
env:
- name: ANSIBLE_KHEOPS_CONFIG
log_level:
description:
- Khéops logging level
choices: ['DEBUG', 'INFO', 'WARNING', 'ERROR']
default: 'WARNING'
env:
- name: ANSIBLE_KHEOPS_LOG_LEVEL
# turfu # Client configuration
# turfu token:
# turfu description:
# turfu - The Kheops token to use to authenticate against Kheops server.
# turfu default: ''
# turfu env:
# turfu - name: ANSIBLE_KHEOPS_TOKEN
# turfu host:
# turfu description:
# turfu - Hostname of the Kheops Server.
# turfu default: '127.0.0.1'
# turfu env:
# turfu - name: ANSIBLE_KHEOPS_HOST
# turfu port:
# turfu description:
# turfu - Kheops port to connect to.
# turfu default: '9843'
# turfu env:
# turfu - name: ANSIBLE_KHEOPS_PORT
# turfu protocol:
# turfu description:
# turfu - The URL protocol to use.
# turfu default: 'http'
# turfu choices: ['http', 'https']
# turfu env:
# turfu - name: ANSIBLE_KHEOPS_PROTOCOL
# turfu validate_certs:
# turfu description:
# turfu - Whether or not to verify the TLS certificates of the Kheops server.
# turfu type: boolean
# turfu default: False
# turfu env:
# turfu - name: ANSIBLE_KHEOPS_VALIDATE_CERTS
# Uneeded # Misc
# Uneeded version:
# Uneeded description:
# Uneeded - Kheops API version to use.
# Uneeded default: 1
# Uneeded choices: [1]
# Uneeded env:
# Uneeded - name: ANSIBLE_KHEOPS_VERSION
# Uneeded cache:
# Uneeded description:
# Uneeded - Enable Kheops inventory cache.
# Uneeded default: false
# Uneeded type: boolean
# Uneeded env:
# Uneeded - name: ANSIBLE_KHEOPS_CACHE
# Uneeded policy:
# Uneeded description:
# Uneeded - Kheops policy to use for the lookups.
# Uneeded default: 'default'
'''
EXAMPLES = '''
# zzz_dev.kheops.yml
plugin: kheops
host: 127.0.0.1
token: xxx:yyy
query_scope:
fqdn: inventory_hostname
# zzz_prod.kheops.yml
plugin: kheops
host: kheops.domain.tld
protocol: https
token: xxx:yyy
query_scope:
fqdn: inventory_hostname
hostgroup: foreman_hostgroup_title
organization: foreman_organization_name
location: foreman_location_name
environment: foreman_environment_name
'''
import sys
import os
import logging
from ansible import constants as C
from ansible.errors import AnsibleError
from ansible.plugins.inventory import BaseInventoryPlugin, Cacheable, Constructable
#import kheops.app as Kheops
from kheops.app import Kheops
sys.path.append("/home/jez/prj/bell/training/tiger-ansible/ext/kheops")
class InventoryModule(BaseInventoryPlugin, Cacheable, Constructable):
NAME = 'kheops'
def verify_file(self, path):
valid = False
if super(InventoryModule, self).verify_file(path):
if path.endswith(('kheops.yaml', 'kheops.yml')):
valid = True
return valid
def parse(self, inventory, loader, path, cache):
'''Return dynamic inventory from source '''
super(InventoryModule, self).parse(inventory, loader, path, cache)
self._read_config_data(path)
# Read configuration
self.keys = self.get_option('query_keys')
self.scope = self.get_option('query_scope')
self.namespace = self.get_option('query_namespace')
self.strict = self.get_option('strict')
self.configuration = self.get_option('configuration')
self.log_level = self.get_option('log_level')
self.cache_enabled = os.environ.get(
'ANSIBLE_KHEOPS_CACHE',
str(self.get_option('cache'))
).lower() in ('true', '1', 't')
# Determine cache behavior
#attempt_to_read_cache = self.cache_enabled and cache
# Khéops instance
kheops = Kheops(config=self.configuration, namespace=self.namespace)
# Khéops log support
log_level = getattr(logging, self.log_level, 'DEBUG')
logger = logging.getLogger('kheops')
logger.setLevel(log_level)
# See for logging: https://medium.com/opsops/debugging-requests-1989797736cc
class ListLoggerHandler(logging.Handler):
def emit(self, record):
msg = self.format(record)
list_logging_handler = ListLoggerHandler()
main_logger = logging.getLogger()
main_logger.addHandler(list_logging_handler)
main_logger.setLevel(logging.DEBUG)
# from pyinstrument import Profiler
#profiler = Profiler()
#profiler.start()
# Loop over each keys
for host_name in inventory.hosts:
host = self.inventory.get_host(host_name)
# Build the scope
scope = {}
host_vars = host.get_vars()
for key, val in self.scope.items():
scope[key] = host_vars.get(val, None)
self.display.vvv(f"Kheops scope for {host.name}: {scope} for keys: {self.keys}")
# Fetch the results
ret = kheops.lookup(
keys=[ key_src for key_dst, key_src in self.keys.items() ],
scope=scope,
#trace=True,
#explain=True,
)
# Inject variables into host
for ansible_key, kheops_key in self.keys.items():
ansible_value = ret.get(kheops_key)
host.set_variable(ansible_key, ansible_value)
# Call constructed inventory plugin methods
hostvars = self.inventory.get_host(host_name).get_vars()
self._set_composite_vars(self.get_option('compose'), hostvars, host_name, self.strict)
self._add_host_to_composed_groups(self.get_option('groups'), hostvars, host_name, self.strict)
self._add_host_to_keyed_groups(self.get_option('keyed_groups'), hostvars, host_name, self.strict)
#profiler.stop()
##profiler.print()
#profiler.open_in_browser()