Add: Kheop inventory plugin
This commit is contained in:
parent
566e6c9e7d
commit
31a52f84f7
252
plugins/inventory/kheops.py
Normal file
252
plugins/inventory/kheops.py
Normal 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()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user