Files
kembit.topdesk/plugins/inventory/topdesk_am.py
2022-05-26 23:12:09 +02:00

211 lines
5.7 KiB
Python

from __future__ import (absolute_import, division, print_function)
from binascii import Incomplete
from email.policy import default
__metaclass__ = type
DOCUMENTATION = r'''
---
name: topdesk_am
short_description: Topdesk Asset Management Inventory
author: Martijn Remmen <mremmen@kembit.nl>
description:
- Constructs an inventory from TOPdesk Asset Management.
options:
url:
type: str
required: true
desciprion:
- The TOPDesk url
username:
type: str
required: true
description:
- A TOPDesk username for authenticating with the TOPDesk API
application_key:
type: str
required: true
description:
- A TOPDesk application key associated with the given username.
- For instructions on creating a key: https://developers.topdesk.com/tutorial.html
fields:
type: list
required: true
description:
- A list of fields from Asset Management that you want to be included
- with the hosts.
names:
type: list
required: true
description:
- A list containing the unique names from all assets you want to include
- in the inventory
ansible_host:
type: str
required: true
description:
- The fieldname of the value to be used as ansible_host.
- This should be the field with a reachable hostname or IP address
groupby:
type: list
description:
- Group hosts based on field(s)
'''
EXAMPLES = '''
'''
from ansible.plugins.inventory import BaseInventoryPlugin
from ansible.utils.display import Display
import requests
display = Display()
class InventoryModule(BaseInventoryPlugin):
NAME = 'kembit.topdesk.topdesk_am'
def __init__(self):
super(BaseInventoryPlugin, self).__init__()
def verify_file(self, path):
# return super().verify_file(path)
return True
def parse(self, inventory, loader, path, cache=True):
super(InventoryModule, self).parse(inventory, loader, path)
self._read_config_data(path)
url = self.get_option('url')
username = self.get_option('username')
application_key = self.get_option('application_key')
fields = self.get_option('fields')
device_names = self.get_option('names')
ansible_host_field = self.get_option('ansible_host')
groupby = self.get_option('groupby')
td = Topdesk(url, username, application_key)
columns, devices = devices_lookup(td, device_names, fields)
column_lookup_table = create_id_lookup_table(td, columns)
replace_ids(devices, column_lookup_table)
# validgroupfields = [group for group in groupby if group in fields]
# groupvalues = dict(default=list)
# for device in devices:
# for groupfield in validgroupfields:
# groupvalues[groupfield]
# device[groupfield]
# self.inventory.add_group(column_lookup_table[group].values())
for device in devices:
name = device['name']
self.inventory.add_host(name)
self.inventory.set_variable(name, 'ansible_host', device[ansible_host_field])
for field, value in device.items():
if field != 'name' and field in fields:
self.inventory.set_variable(name, field, value)
display.display(f"Added {len(devices)} hosts")
class Topdesk:
def __init__(self, url: str, username: str, application_key: str) -> None:
self.url = url
self.api_url = url + '/tas/api'
self._session = requests.Session()
self._session.auth = (username, application_key)
self._headers = {'accept': 'application/json'}
def get(self, endpoint: str, **kwargs) -> requests.Request:
return self._session.get(self.api_url + endpoint, **kwargs)
def get_asset(td: Topdesk, parameters: dict):
return td.get('/assetmgmt/assets', params=parameters)
def create_parameters(
fields: list[str],
name: str,
includefunctionalities: bool = False,
includesettings: bool = False,
includetemplates: bool = False
):
return {
'fields': ','.join(fields),
'$filter': f'name eq {name}',
'includeFunctionalities': str(includefunctionalities),
'includeSettings': str(includesettings),
'includeTemplates': str(includetemplates)
}
def create_id_lookup_table(td: Topdesk, columns: dict) -> dict:
table = {}
for columnname, columndata in columns.items():
column_properties = columndata.get('properties')
if not column_properties:
continue
column_url = column_properties.get('url')
if column_url:
data = td.get("/assetmgmt/" + column_url).json()['dataSet']
table.update({columnname: {value['id']: value['text'] for value in data}})
return table
def devices_lookup(td: Topdesk, device_names: list[str], fields: list[str]):
columns = {}
devices = []
for device in device_names:
params = create_parameters(fields, device)
data = get_asset(td, params).json()
columns.update({column['fieldName']: column for column in data['columns']})
devices.extend(data['dataSet'])
return columns, devices
def replace_ids(devices, column_lookup_table):
for device in devices:
for fieldname, fieldvalue in device.items():
if fieldname in column_lookup_table.keys():
if fieldvalue: # soms is het None
device[fieldname] = column_lookup_table[fieldname][fieldvalue]
def main():
pass
if __name__ == '__main__':
main()