122 lines
3.4 KiB
Python
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!')
|
|
|