pvl.hosts.config: document includes, fix include-only zone, and test
authorTero Marttila <tero.marttila@aalto.fi>
Thu, 26 Feb 2015 17:36:55 +0200
changeset 507 e3a32f4dff54
parent 506 b19104afe1b4
child 508 a47849709cbf
pvl.hosts.config: document includes, fix include-only zone, and test
README
etc/hosts/includes.test
etc/hosts/includes.test.d/bar
etc/hosts/includes.test.d/foo
pvl/hosts/config.py
pvl/hosts/tests.py
--- a/README	Thu Feb 26 17:36:23 2015 +0200
+++ b/README	Thu Feb 26 17:36:55 2015 +0200
@@ -42,6 +42,22 @@
         fixed-address 127.0.0.2;
     }
 
+=== Include confs ===
+Host configs can be included:
+
+    $ cat etc/hosts/includes.test
+    include = includes.test.d/
+
+    $ cat etc/hosts/includes.test.d/foo 
+    ip = 192.0.2.1
+
+    $ cat etc/hosts/includes.test.d/bar 
+    ip = 192.0.2.2
+
+    $ ./opt/bin/python bin/pvl.hosts-forward --forward-zone test etc/hosts/includes.test
+    foo.includes                      A     192.0.2.1
+    bar.includes                      A     192.0.2.2
+
 === Host aliases ===
 Hosts can specify DNS aliases:
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/etc/hosts/includes.test	Thu Feb 26 17:36:55 2015 +0200
@@ -0,0 +1,1 @@
+include = includes.test.d/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/etc/hosts/includes.test.d/bar	Thu Feb 26 17:36:55 2015 +0200
@@ -0,0 +1,1 @@
+ip = 192.0.2.2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/etc/hosts/includes.test.d/foo	Thu Feb 26 17:36:55 2015 +0200
@@ -0,0 +1,2 @@
+ip = 192.0.2.1
+
--- a/pvl/hosts/config.py	Thu Feb 26 17:36:23 2015 +0200
+++ b/pvl/hosts/config.py	Thu Feb 26 17:36:55 2015 +0200
@@ -225,19 +225,19 @@
     section = dict(defaults)
     for scalar in config.scalars:
         section[scalar] = config[scalar]
-    
+
+    # process includes?
+    includes = section.pop('include', '')
+
+    for file in apply_hosts_includes(options, path, includes):
+        # within our domain context
+        for host in apply_hosts_file(options, file, parent=name):
+            yield host
+
     if config.sections:
         # this is a top-level section that includes hosts
         log.info("%s: @%s", path, name)
 
-        # process includes?
-        includes = section.pop('include', '')
-
-        for file in apply_hosts_includes(options, path, includes):
-            # within our domain context
-            for host in apply_hosts_file(options, file, parent=name):
-                yield host
-
         # recurse until we hit a scalar-only section representing a host
         for section_name in config.sections:
             log.debug("%s: %s: %s", path, name, section_name)
@@ -260,6 +260,10 @@
 
             raise HostConfigError(path, "{parent}: {name}: {error}".format(parent=parent, name=name, error=error))
 
+    elif includes:
+        # includes-only zone
+        pass
+
     else:
         raise HostConfigError(path, "No sections in config")
 
--- a/pvl/hosts/tests.py	Thu Feb 26 17:36:23 2015 +0200
+++ b/pvl/hosts/tests.py	Thu Feb 26 17:36:55 2015 +0200
@@ -95,7 +95,7 @@
         with self.assertRaises(config.HostConfigError):
             list(config.apply_hosts_files(self.options, ['nonexistant']))
 
-    def testApplyHosts(self):
+    def testApplyHostsFile(self):
         conf_file = ConfFile('test', """
 [foo]
     ip = 127.0.0.1
@@ -110,6 +110,16 @@
 
         self.assertHostsEqual(config.apply_hosts_file(self.options, conf_file), expected)
 
+    def testApplyIncludes(self):
+        self.assertHostsEqual(config.apply_hosts_files(self.options, ['etc/hosts/includes.test']), [
+                ('foo@includes.test', dict(
+                    ip          = ipaddr.IPAddress('192.0.2.1'),
+                )),
+                ('bar@includes.test', dict(
+                    ip          = ipaddr.IPAddress('192.0.2.2'),
+                )),
+        ])
+
     def testApply(self):
         self.assertHostsEqual(config.apply(self.options, ['etc/hosts/test']), [
                 ('foo@test', dict(