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 description: - Constructs an inventory from TOPdesk Asset Management. options: url: type: str required: true description: - 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()