refactor code to use new OneDNS api class

- OneDNS class provides VM -> DNS interface
- Updated OneMonitor to subclass OneDNS
- Moved 'register' method from skydns client to OneDNS as add_vm
- Moved 'update' method from OneMonitor to OneDNS as sync
- Added methods to OneDNS to add/remove VMs by id
master
Justin Riley 2016-07-21 09:46:04 -04:00
parent 388739a2e0
commit 9bcddf29ad
3 changed files with 77 additions and 34 deletions

59
onedns/api.py Normal file
View File

@ -0,0 +1,59 @@
from onedns.clients import one
from onedns.clients import skydns
from onedns.logger import log
class OneDNS(object):
"""
This class bridges the gap between OpenNebula and SkyDNS APIs. It primarily
provides convenience methods for adding/removing VMs to SkyDNS.
"""
def __init__(self, domain, one_kwargs={}, etcd_kwargs={}):
self._one = one.OneClient(**one_kwargs)
self._skydns = skydns.SkyDNSClient(domain, etcd_kwargs=etcd_kwargs)
def _get_vm_dns_entries(self, vm):
entries = {}
if not hasattr(vm.template, 'nics'):
return entries
hostname = vm.name
primary_ip = vm.template.nics[0].ip
entries[hostname] = primary_ip
for nic in vm.template.nics[1:]:
nicname = "{hostname}-{id}".format(hostname=hostname,
id=nic.nic_id)
entries[nicname] = nic.ip
return entries
def add_vm(self, vm):
dns_entries = self._get_vm_dns_entries(vm)
if not dns_entries:
log.warn("No networks found for VM {id}: {vm} - skipping".format(
vm=vm.name, id=vm.id))
return
log.info("Adding VM {id}: {vm}".format(id=vm.id, vm=vm.name))
for name, ip in dns_entries.items():
self._skydns.add_host(name, ip)
def remove_vm(self, vm):
dns_entries = self._get_vm_dns_entries(vm)
if not dns_entries:
log.warn("No networks found for VM {id}: {vm} - skipping".format(
vm=vm.name, id=vm.id))
return
log.info("Removing VM {id}: {vm}".format(id=vm.id, vm=vm.name))
for name, ip in dns_entries.items():
self._skydns.remove_host(name, ip)
def add_vm_by_id(self, vm_id):
vm = self._one.get_vm_by_id(vm_id)
return self.add_vm(vm)
def remove_vm_by_id(self, vm_id):
vm = self._one.get_vm_by_id(vm_id)
return self.remove_vm(vm)
def sync(self):
for vm in self._one.vms():
self.add_vm(vm)

View File

@ -15,6 +15,9 @@ class SkyDNSClient(object):
self._reverse_domain_parts.reverse()
self._etcd = etcd.Client(**etcd_kwargs)
def _sanitize_name(self, name):
return RE_VALIDNAME.sub('', name).rstrip('.')
def _skydns_ns(self, parts):
return '/'.join(['skydns'] + parts)
@ -27,10 +30,10 @@ class SkyDNSClient(object):
def add_forward(self, hostname, ip):
forward = self._get_forward_ns(hostname)
log.debug("forward path: {path}".format(path=forward))
log.debug("adding forward: {path}".format(path=forward))
self._etcd.write(forward, json.dumps(dict(host=ip)))
def remove_forward(self, hostname, ip):
def remove_forward(self, hostname):
forward = self._get_forward_ns(hostname)
log.debug("removing forward: {path}".format(path=forward))
self._etcd.delete(forward)
@ -38,28 +41,20 @@ class SkyDNSClient(object):
def add_reverse(self, ip, hostname):
reverse = self._get_reverse_ns(ip)
fqdn = '.'.join([hostname, self.domain])
log.debug("reverse path: {path}".format(path=reverse))
log.debug("adding reverse: {path}".format(path=reverse))
self._etcd.write(reverse, json.dumps(dict(host=fqdn)))
def remove_reverse(self, ip, hostname):
def remove_reverse(self, ip):
reverse = self._get_reverse_ns(ip)
log.debug("removing reverse: {path}".format(path=reverse))
self._etcd.delete(reverse)
def add_host(self, hostname, ip):
hostname = self._sanitize_name(hostname)
self.add_forward(hostname, ip)
self.add_reverse(ip, hostname)
def remove_host(self, hostname, ip):
self.remove_forward(hostname, ip)
self.remove_reverse(ip, hostname)
def register(self, vm):
log.info("Registering VM: {vm}".format(vm=vm.name))
hostname = RE_VALIDNAME.sub('', vm.name).rstrip('.')
primary_ip = vm.template.nics[0].ip
self.add_host(hostname, primary_ip)
for nic in vm.template.nics[1:]:
nicname = "{hostname}-{id}".format(hostname=hostname,
id=nic.nic_id)
self.add_host(nicname, nic.ip)
hostname = self._sanitize_name(hostname)
self.remove_forward(hostname)
self.remove_reverse(ip)

View File

@ -1,24 +1,13 @@
import time
from onedns.clients import one
from onedns.clients import skydns
from onedns import api
class OneMonitor(object):
'''
Reads events from OpenNebula and activates/deactivates VM domain names
'''
def __init__(self, domain, one_kwargs={}, etcd_kwargs={}):
self._one = one.OneClient(**one_kwargs)
self._skydns = skydns.SkyDNSClient(domain, etcd_kwargs=etcd_kwargs)
def update(self):
for vm in self._one.vms():
if hasattr(vm.template, 'nics'):
self._skydns.register(vm)
def run(self, interval=10):
class OneMonitor(api.OneDNS):
"""
Daemon that syncs OpenNebula VMs with SkyDNS
"""
def run(self, interval=60):
while True:
self.update()
self.sync()
time.sleep(interval)