-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathansible-dynamic-inventory.py
executable file
·116 lines (86 loc) · 3.29 KB
/
ansible-dynamic-inventory.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Dynamic Ansible Inventory based on LibreNMS API access.
"""
import argparse
import requests
import json
import re
parser = argparse.ArgumentParser(description='Return LibreNMS devices as a dynamic Ansible inventory.')
parser.add_argument('--list', help="return a list of full inventory of hosts", action="store_true")
parser.add_argument('--host', help="return hostsvars for a single host")
args = parser.parse_args()
librenms_hostname = 'https://hostname.example'
librenms_auth_token = 'replace-with-token'
headers = {
'X-Auth-Token': librenms_auth_token,
}
def get_device_details(device):
"""
Takes a device object and returns a dict with the relevant details.
"""
_device_details = {
'sysname': device['sysName'],
'hardware': device['hardware'],
'location': device['location'],
'type': device['type'],
'ansible_network_os': device['os'],
}
return(_device_details)
def return_single_host(hostname):
"""
Return the host variables for a single host.
"""
r = requests.get(librenms_hostname + '/api/v0/devices/' + hostname, headers=headers)
devices = json.loads(r.text)
device = devices['devices'][0]
device_details = get_device_details(device)
print(json.dumps(device_details))
def return_full_inventory():
"""
Return a full ansible inventory.
"""
r = requests.get(librenms_hostname + '/api/v0/devices', headers=headers)
librenms_devices = json.loads(r.text)
# Create the basic inventory structure.
# - http://docs.ansible.com/ansible/devel/dev_guide/developing_inventory.html
# Do not create the 'ungrouped' group unless we truly have ungrouped, as per this bug:
# https://github.com/ansible/ansible/pull/45621
ansible_inventory = {
"_meta": {
"hostvars": {},
},
"all": {
"children": []
},
}
for device in librenms_devices['devices']:
# Get the device type, based on our internal Naming Scheme (asw, csw, dsw, etc.)
# - https://librenms1.rootdom.dk/plugin/p=Namingscheme
device_type = re.match("^([a-zA-Z]*).*", device['hostname']).group(1)
# Handle devices not matching our Naming Scheme
if device_type == '':
device_type = 'ungrouped'
# Create a group for the device type if we don't already have one
try:
if (ansible_inventory[device_type]):
pass
except KeyError:
ansible_inventory[device_type] = {
'hosts': [],
'vars': {
'connection': 'network_cli',
}
}
ansible_inventory['all']['children'].append(device_type)
hostname = device['hostname']
# Add the host to the relevant device group
ansible_inventory[device_type]['hosts'].append(hostname)
# Add the host details to the _meta.hostvars dict
ansible_inventory['_meta']['hostvars'][hostname] = get_device_details(device)
print(json.dumps(ansible_inventory))
if args.host:
return_single_host(args.host)
elif args.list:
return_full_inventory()