# Copyright 2016 Cloudbase Solutions Srl # All Rights Reserved. # # Author: Alin Balutoiu # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import six from oslo_config import cfg from oslo_log import log as logging from os_win import utilsfactory from os_win import constants from os_win import exceptions as os_win_exc from designate.backend.agent_backend import base from designate import exceptions LOG = logging.getLogger(__name__) class MSDNSBackend(base.AgentBackend): __plugin_name__ = 'msdns' __backend_status__ = 'experimental' def __init__(self, agent_service): """Configure the backend""" super(MSDNSBackend, self).__init__(agent_service) self._dnsutils = utilsfactory.get_dnsutils() masters = cfg.CONF['service:agent'].masters if not masters: raise exceptions.Backend("Missing agent AXFR masters") # Only ip addresses are needed self._masters = [ns.split(":")[0] for ns in masters] LOG.info("AXFR masters: %r", self._masters) def start(self): """Start the backend""" LOG.info("Started msdns backend") def find_zone_serial(self, zone_name): """Return the zone's serial""" zone_name = zone_name.rstrip(".") LOG.debug("Finding zone: %s", zone_name) try: return self._dnsutils.get_zone_serial(zone_name) except os_win_exc.DNSZoneNotFound: # Return None if the zone was not found return None def create_zone(self, zone): """Create a new DNS Zone""" zone_name = zone.origin.to_text(omit_final_dot=True) if six.PY3 and isinstance(zone_name, bytes): zone_name = zone_name.decode('utf-8') LOG.debug("Creating zone: %s", zone_name) try: self._dnsutils.zone_create( zone_name=zone_name, zone_type=constants.DNS_ZONE_TYPE_SECONDARY, ds_integrated=False, ip_addrs=self._masters) except os_win_exc.DNSZoneAlreadyExists: # Zone already exists, check its properties to see if the # existing zone is identical to the requested one zone_properties = self._dnsutils.get_zone_properties(zone_name) identical_zone_exists = ( zone_properties['zone_type'] == ( constants.DNS_ZONE_TYPE_SECONDARY) and zone_properties['ds_integrated'] is False and set(zone_properties['master_servers']) == set(self._masters)) if not identical_zone_exists: raise def update_zone(self, zone): """Instruct MSDNS to request an AXFR from MiniDNS. """ zone_name = zone.origin.to_text(omit_final_dot=True) if six.PY3 and isinstance(zone_name, bytes): zone_name = zone_name.decode('utf-8') LOG.debug("Updating zone: %s", zone_name) self._dnsutils.zone_update(zone_name) def delete_zone(self, zone_name): """Delete a DNS Zone Do not raise exception if the zone does not exist. """ LOG.debug('Deleting zone: %s' % zone_name) zone_name = zone_name.rstrip(".") self._dnsutils.zone_delete(zone_name)