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