Get rid of _delegation_callback
[invirt/packages/invirt-dns.git] / invirt-dns
index d5fa021..60787a0 100755 (executable)
@@ -45,7 +45,7 @@ class DatabaseAuthority(common.ResolverBase):
         for i in range(3):
             try:
                 value = self._lookup_unsafe(name, cls, type, timeout = None)
-            except (psycopg2.OperationalError, sqlalchemy.exceptions.SQLError):
+            except (psycopg2.OperationalError, sqlalchemy.exceptions.DBAPIError):
                 if i == 2:
                     raise
                 print "Reloading database"
@@ -127,7 +127,7 @@ class DatabaseAuthority(common.ResolverBase):
             if value:
                 ip = value.ip
             else:
-                value = invirt.database.Machine.query().filter_by(name=host).first()
+                value = invirt.database.Machine.query.filter_by(name=host).first()
                 if value:
                     ip = value.nics[0].ip
                 else:
@@ -147,9 +147,9 @@ class DatabaseAuthority(common.ResolverBase):
             additional = []
         return defer.succeed((results, authority, additional))
 
-class QuotingBindAuthority(authority.BindAuthority):
+class DelegatingQuotingBindAuthority(authority.BindAuthority):
     """
-    A BindAuthority that (almost) deals with quoting correctly
+    A delegating BindAuthority that (almost) deals with quoting correctly
     
     This will catch double quotes as marking the start or end of a
     quoted phrase, unless the double quote is escaped by a backslash
@@ -194,12 +194,29 @@ class QuotingBindAuthority(authority.BindAuthority):
             L.append(split_line)
         return filter(None, L)
 
+    def _lookup(self, name, cls, type, timeout = None):
+        deferredResult = authority.BindAuthority._lookup(self, name, cls,
+                                                         type, timeout)
+        # If we didn't find an exact match for the name we were seeking,
+        # check if it's within a subdomain we're supposed to delegate to
+        # some other DNS server.
+        deferredResult.addErrback(self._delegation_errback, name, cls, timeout)
+        return deferredResult
+
+    def _delegation_errback(self, deferredResult, name, cls, timeout):
+        if '.' in name:
+            name = name[name.find('.') + 1 :]
+            deferredResult = authority.BindAuthority._lookup(self, name, cls,
+                                                             dns.NS, timeout)
+            deferredResult.addErrback(self._delegation_errback, name, cls, timeout)
+        return deferredResult
+
 if '__main__' == __name__:
     resolvers = []
     try:
         for zone in config.dns.zone_files:
             for origin in config.dns.domains:
-                r = QuotingBindAuthority(zone)
+                r = DelegatingQuotingBindAuthority(zone)
                 # This sucks, but if I want a generic zone file, I have to
                 # reload the information by hand
                 r.origin = origin