vmtool/ovhtool.py

122 lines
3.4 KiB
Python

#!/usr/bin/env python
'''ovhtool - OVH IP address management tool
usage: ovhtool <command>
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 '<OVHIP {0.ip} {0.mac} {0.domain}>'.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['<command>'] == '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['<command>'] == '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!')