server: implement tiebreaker for VMs with same name/IP
The tiebreaker is first-come first serve - ie whichever VM had the name or IP first wins (based on VM id). The sync() method now sorts the VM list by id in order to evaluate the tiebreaker correctly (VM list comes that way from ONED but just in case...).master
parent
a7051e0689
commit
4c245819ce
|
@ -36,3 +36,11 @@ class RecordDoesNotExist(OneDnsException):
|
|||
self.msg = "Record Does Not Exist: {}".format(key)
|
||||
if val is not None:
|
||||
self.msg += " -> {}".format(val)
|
||||
|
||||
|
||||
class DuplicateVMError(OneDnsException):
|
||||
"""
|
||||
Raised when two or more VMs share a name or IP
|
||||
"""
|
||||
def __init__(self, vmid, key, val):
|
||||
self.msg = "VM one-{} has a duplicate: {} -> {}".format(vmid, key, val)
|
||||
|
|
|
@ -31,10 +31,24 @@ class OneDNS(resolver.DynamicResolver):
|
|||
entries[nicname] = nic.ip
|
||||
return entries
|
||||
|
||||
def _check_for_duplicates(self, vm_id, name, ip, zone=None):
|
||||
z = zone or self.zone
|
||||
try:
|
||||
f = z.get_forward(name)
|
||||
raise exception.DuplicateVMError(vm_id, f, ip)
|
||||
except exception.RecordDoesNotExist:
|
||||
pass
|
||||
try:
|
||||
r = z.get_reverse(ip)
|
||||
raise exception.DuplicateVMError(vm_id, ip, r)
|
||||
except exception.RecordDoesNotExist:
|
||||
pass
|
||||
|
||||
def add_vm(self, vm, zone=None):
|
||||
dns_entries = self._get_vm_dns_entries(vm)
|
||||
log.info("Adding VM {id}: {vm}".format(id=vm.id, vm=vm.name))
|
||||
for name, ip in dns_entries.items():
|
||||
self._check_for_duplicates(vm.id, name, ip, zone=zone)
|
||||
self.add_host(name, ip, zone=zone)
|
||||
|
||||
def remove_vm(self, vm, zone=None):
|
||||
|
@ -54,9 +68,12 @@ class OneDNS(resolver.DynamicResolver):
|
|||
def sync(self, vms=None):
|
||||
z = zone.Zone(self.domain)
|
||||
vms = vms or self._one.vms()
|
||||
vms.sort(key=lambda x: x.id)
|
||||
for vm in vms:
|
||||
try:
|
||||
self.add_vm(vm, zone=z)
|
||||
except exception.NoNetworksError as e:
|
||||
e.log(warn=True)
|
||||
except exception.DuplicateVMError as e:
|
||||
e.log(warn=True)
|
||||
self.load(z)
|
||||
|
|
Loading…
Reference in New Issue