diff --git a/onedns/exception.py b/onedns/exception.py index eac61f0..06b5f16 100644 --- a/onedns/exception.py +++ b/onedns/exception.py @@ -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) diff --git a/onedns/server.py b/onedns/server.py index e504d92..70defaa 100644 --- a/onedns/server.py +++ b/onedns/server.py @@ -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)