Skip to content

Instantly share code, notes, and snippets.

@meantheory
Created November 2, 2016 18:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save meantheory/675230bfabff0dc63640799f3139b5e3 to your computer and use it in GitHub Desktop.
Save meantheory/675230bfabff0dc63640799f3139b5e3 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
"""
Packet external inventory script
=================================
Usage: copy file to `/etc/ansible/hosts` and chmod +x the file.
This script sources data from the Packet api.
"""
# import argparse
# import configparser
import os
import re
import json
import packet
from time import time
from collections import defaultdict
_packet_config = {
'simple_config': 'values here',
'packet_auth_token': 'an auth token goes here',
'packet_project_id': 'a project id goes here',
'a_well_named_config_variable': 'v4_public', #v4_private, v6_public are also valid keys.
'pretty_print': True,
}
class Config:
@staticmethod
def get(key):
return _packet_config[key]
class PacketInventory(object):
def __init__(self):
# setup packet api
token = Config.get('packet_auth_token')
self.packet = packet.Manager(auth_token=token)
# build packet inventory and print it so ansible can consume it
data = self.build_inventory()
print(self._dumps(data))
def _dumps(self, data):
pretty = Config.get('pretty_print')
if pretty:
return json.dumps(data, sort_keys=True, indent=2)
else:
return json.dumps(data)
def _ip_map(self, iplist):
def is_public(val):
if val:
return 'public'
else:
return 'private'
ipmap = {}
for address in iplist:
key = 'v' + str(address['address_family'])
key += '_' + is_public(address['public'])
ipmap[key] = address
return ipmap
def _host_data(self, ip, host):
host_data = {
'ansible_ssh_host': ip['address'],
'packet_ip_address': ip['address'],
'packet_ip_gateway': ip['gateway'],
'packet_ip_netmask': ip['netmask'],
'packet_ip_network': ip['network'],
'packet_ip_cidr': ip['cidr'],
'packet_os_name': host.operating_system.name,
'packet_os_distro': host.operating_system.distro,
'packet_os_slug': host.operating_system.slug,
'packet_os_version': host.operating_system.version,
'packet_hostname': host.hostname,
'packet_facility': host.facility,
'packet_facility_code': host.facility['code'],
'packet_state': host.state,
'packet_created_at': host.created_at,
'packet_updated_at': host.updated_at,
}
return host_data
def _extract_data(self, hosts):
inventory = {}
tags = defaultdict(list)
for host in hosts:
# todo: explore the use of host.tags
# todo: explore the use of host.userdata
# assumption: always 3 ip addresses, one of each(ipv6, ipv4 public, ipv4 private)
# classify by ip type we are indexing on
ip_key = Config.get('a_well_named_config_variable')
ip_index = self._ip_map(host.ip_addresses)
ip = ip_index[ip_key]
# generate host data
inventory[ip['address']] = self._host_data(ip, host)
# generate tags
key_distro = 'key_distro_' + host.operating_system.distro
tags[key_distro].append(ip['address'])
return inventory, tags
def build_inventory(self):
project = Config.get('packet_project_id')
hosts = self.packet.list_devices(project)
hostvars, tags = self._extract_data(hosts)
# build and return the ansible inventory formatted data
inventory = {
'_meta':
{'hostvars': hostvars},
}
inventory.update(tags)
return inventory
if __name__ == '__main__':
PacketInventory()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment