# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
import isc.dns
+import isc.ddns.zone_config
# Result codes for UpdateSession.handle()
UPDATE_DONE = 0 # handled completely, and the response is ready
TBD
'''
- def __init__(self, req_message, req_data, client_addr, datasrc_client):
+ def __init__(self, req_message, req_data, client_addr, zone_config):
self.__message = req_message
+ self.__zone_config = zone_config
def get_message(self):
'''Return the update message.
'''
try:
- zone_record = self.__get_update_zone()
+ datasrc_client, zname, zclass = self.__get_update_zone()
+ # conceptual code that would follow
+ # self.__check_prerequisites()
+ # self.__check_update_acl()
+ # self.__do_update()
+ # self.__make_response(Rcode.NOERROR())
except ZoneError as e:
self.__make_response(e.rcode)
return UPDATE_DONE
def __get_update_zone(self):
- '''Interpret the zone section and return it as a Question object.
+ '''Parse the zone section and find the zone to be updated.
- It must contain exactly one question, and it must be of type SOA.
+ If the zone section is valid and the specified zone is found in
+ the configuration, it returns a tuple of:
+ - A matching data source that contains the specified zone
+ - The zone name as a Name object
+ - The zone class as an RRClass object
'''
+ # Validation: the zone section must contain exactly one question,
+ # and it must be of type SOA.
if self.__message.get_rr_count(SECTION_ZONE) != 1:
raise ZoneError('Invalid number of records in zone section: ' +
str(1), isc.dns.Rcode.FORMERR())
- zone_record = self.__message.get_question()[0]
- if zone_record.get_type() != isc.dns.RRType.SOA():
+ zrecord = self.__message.get_question()[0]
+ if zrecord.get_type() != isc.dns.RRType.SOA():
raise ZoneError('update zone section contains non-SOA',
isc.dns.Rcode.FORMERR())
- return zone_record
+
+ # See if we're serving a primary zone specified in the zone section.
+ zname = zrecord.get_name()
+ zclass = zrecord.get_class()
+ zone_type, datasrc_client = self.__zone_config.find_zone(zname, zclass)
+ if zone_type == isc.ddns.zone_config.ZONE_PRIMARY:
+ return datasrc_client, zname, zclass
def __make_response(self, rcode):
'''Transform the internal message to the update response.
import unittest
from isc.dns import *
from isc.ddns.session import *
+from isc.ddns.zone_config import *
# Some common test parameters
TEST_ZONE_NAME = Name('example.com')
self.__update_msgdata, self.__update_msg = create_update_msg()
self.__session = UpdateSession(self.__update_msg,
self.__update_msgdata,
- self.__client_addr, None)
+ self.__client_addr, ZoneConfig())
def check_response(self, msg, expected_rcode):
'''Perform common checks on update resposne message.'''
--- /dev/null
+# Copyright (C) 2012 Internet Systems Consortium.
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
+# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+# Constants representing zone types
+ZONE_NOTFOUND = -1 # Zone isn't found in find_zone()
+ZONE_PRIMARY = 0 # Primary zone
+ZONE_SECONDARY = 1 # Secondary zone
+
+class ZoneConfig:
+ '''A temporary helper class to encapsulate zone related configuration.
+
+ Its find_zone method will search the conceptual configuration for a
+ given zone, and return a tuple of zone type (primary or secondary) and
+ the client object to access the data source stroing the zone.
+ It's very likely that details of zone related configurations like this
+ will change in near future, so the main purpose of this class is to
+ provide an independent interface for the main DDNS session module
+ until the details are fixed.
+
+ '''
+ def find_zone(self, zone_name, zone_class):
+ '''Return the type and accessor client object for given zone.'''
+ # Right now, the client is not used, so we simply return None.
+ return ZONE_PRIMARY, None