#!/usr/bin/env python '''ovhtool - OVH IP address management tool usage: ovhtool Available commands are: list Lists IP addresses sync Creates vmac records where missing ''' import logging logger = logging.getLogger(__name__) logging.basicConfig(level=logging.DEBUG) import os import re import ovh import netaddr from docopt import docopt try: import libvirt except: libvirt = None logger.warning('No libvirt - not using IP availability data') from xml.dom import minidom current_server = None class OVHIP(object): def __init__(self, ip, mac, domain): self.ip = ip self.mac = mac self.domain = domain def __repr__(self): return ''.format(self) def parse_ovhrc(fd): config = {} for l in fd: if l.strip().startswith('#'): continue try: key, value = re.match('(.*)="(.*)"', l).groups() config[key] = value except: logging.debug('Invalid config line: %r', l, exc_info=True) return config def server_detect(client): ovhrc_path = os.path.expanduser('~/.ovhrc') if os.path.exists(ovhrc_path): with open(ovhrc_path) as fd: ovhrc = parse_ovhrc(fd) return ovhrc['SERVERNAME'] return client.get('/dedicated/server')[0] def list_ips(server=None, client=None): domains = {} if libvirt: c = libvirt.openReadOnly(None) for domid in c.listDomainsID(): domain = c.lookupByID(domid) domains[domid] = [] dom = minidom.parseString(domain.XMLDesc(0)) for interface in dom.getElementsByTagName('interface'): mac = interface.getElementsByTagName('mac')[0].getAttribute('address') domains[mac.lower()] = domain client = client or ovh.Client() if not server: server = server_detect(client) ips = {} for net in client.get('/ip?routedTo.serviceName=%s&type=failover' % server): for addr in netaddr.IPNetwork(net): ips[str(addr)] = OVHIP(str(addr), None, None) macs = client.get('/dedicated/server/%s/virtualMac' % server) for mac in macs: resp = client.get('/dedicated/server/%s/virtualMac/%s/virtualAddress' % (server, mac))[0] ips[resp].mac = mac ips[resp].domain = domains.get(mac.lower()) return ips if __name__ == "__main__": args = docopt(__doc__, version='ovhtool 0.1') if args[''] == 'list': ips = list_ips() for _, ip in ips.items(): hostname = ip.domain.name() if ip.domain else '' print '%15s | %17s | %s' % (ip.ip, ip.mac, hostname) elif args[''] == 'sync': client = ovh.Client() server = client.get('/dedicated/server')[0] ips = list_ips(client=client) for ip in ips.values(): if ip.mac is None: try: logger.info('Missing MAC for %s, creating', ip.ip) resp = client.post('/dedicated/server/%s/virtualMac' % (server,), ipAddress=ip.ip, type='ovh', virtualMachineName='vm') logger.info('Result: %r', resp) except: logger.exception('Failed!')