]> git.apps.os.sepia.ceph.com Git - ceph-cm-ansible.git/commitdiff
nameserver: Support dynamic DNS zone in records task
authorDavid Galloway <dgallowa@redhat.com>
Thu, 8 Dec 2016 20:13:26 +0000 (15:13 -0500)
committerDavid Galloway <dgallowa@redhat.com>
Fri, 16 Dec 2016 19:53:22 +0000 (14:53 -0500)
Signed-off-by: David Galloway <dgallowa@redhat.com>
roles/nameserver/README.rst
roles/nameserver/tasks/records.yml

index d30806cc30521a8433d9b92f6203670d551e92e8..3c403eac1b50c00d1b5df48485d189e83776943b 100644 (file)
@@ -74,7 +74,7 @@ Most variables are defined in ``roles/nameserver/defaults/main.yml`` and values
 
 **named_domains: []**
 
-The ``named_domains`` dictionary is the bread and butter of creating zone files.  It is in standard YAML syntax.  Each domain (key) must have ``forward`` and ``ipvar`` defined although ``ipvar`` can be set to ``NULL``.  Optional values include ``miscrecords`` and ``reverse``.
+The ``named_domains`` dictionary is the bread and butter of creating zone files.  It is in standard YAML syntax.  Each domain (key) must have ``forward``, ``ipvar``, and ``dynamic`` defined.  ``ipvar`` can be set to ``NULL``.  Optional values include ``miscrecords``, ``reverse``, and ``ddns_hostname_prefixes``.
 
 ``forward``
   The domain of the forward lookup zone for each domain (key)
@@ -82,6 +82,12 @@ The ``named_domains`` dictionary is the bread and butter of creating zone files.
 ``ipvar``
   The variable assigned to a system in the Ansible inventory.  This allows systems to have multiple IPs assigned for a front and ipmi network, for example.  See **Inventory Example** below.
 
+``dynamic``
+  Specifies whether the parent zone/domain should allow Dynamic DNS records.  See **Dynamic DNS** below for more information.
+
+``ddns_hostname_prefixes``
+  This should be a list of dynamic hostname prefixes you don't want overwritten if a zone/domain has static and dynamic records.  See **Dynamic DNS** below.
+
 ``miscrecords``
   Records to add to corresponding ``forward`` zone file.  This is a good place for CNAMEs and MX records and records for hosts you don't have in your Ansible inventory.  If your main nameserver is in a subdomain, you should create its glue record here.  See example.
 
@@ -93,6 +99,7 @@ The ``named_domains`` dictionary is the bread and butter of creating zone files.
     named_domains:
       example.com:
         ipvar: NULL
+        dynamic: false
         forward: example.com
         miscrecords:
           - www                 IN      A       8.8.8.8
@@ -100,6 +107,9 @@ The ``named_domains`` dictionary is the bread and butter of creating zone files.
           - ns1.private         IN      A       192.168.0.1
       private.example.com:
         ipvar: ip
+        dynamic: true
+        ddns_hostname_prefixes:
+          - dyn
         forward: private.example.com
         miscrecords:
           - mail                IN      MX      192.168.0.2
@@ -110,11 +120,15 @@ The ``named_domains`` dictionary is the bread and butter of creating zone files.
           - 192.168.2.0
       mgmt.example.com:
         ipvar: mgmt
+        dynamic: false
         forward: mgmt.example.com
         reverse:
           - 192.168.10.0
           - 192.168.11.0
           - 192.168.12.0
+      ddns.example.com:
+        ipvar: NULL
+        dynamic: true
         
 Inventory
 +++++++++
index c66b09c0cd85b2edc497eff7a1e06a7fd6cd59e7..de154c567b4c1bb9a321fb29cce7e0bcce73b0b4 100644 (file)
   set_fact:
     named_serial: "{{ ansible_date_time.epoch }}"
 
+- name: Create non-existent forward zone files for dynamic domains
+  template:
+    src: forward.j2
+    dest: "{{ named_conf_zones_path }}/{{ item.key }}"
+    validate: named-checkzone {{ item.key }} %s
+    # only write if zone file doesn't already exist
+    # this makes sure we don't clobber ddns records
+    force: no
+  with_dict: "{{ named_domains }}"
+  notify: reload named
+  when: item.value.dynamic == true
+
+# This makes sure dynamic DNS records in the journal files are in sync with the
+# actual zone files so we can store them in the next step.
+- name: Sync Dynamic DNS journals with zone files
+  command: "rndc sync -clean {{ item.key }}"
+  with_dict: "{{ named_domains }}"
+  when: item.value.dynamic == true and
+        item.value.ddns_hostname_prefixes is defined
+  # Don't fail if there is no journal file
+  failed_when: false
+
+- name: Create temporary directory for dynamic A records
+  command: "mktemp -d"
+  register: named_tempdir
+
+# We need to store existing DNS records in a temp file so we can spit
+# them back out into the zone file after static records are written.
+# Given hostname prefix(es) to expect, this task greps for those records
+# and stores them in a temporary file named after the domain.
+- name: Store existing dynamic A records
+  shell: "grep -E '^({% for prefix in item.value.ddns_hostname_prefixes %}{{ prefix }}{% if not loop.last %}|{% endif %}{% endfor %})[0-9]+\\s+A' {{ named_conf_zones_path }}/{{ item.key }} > {{ named_tempdir.stdout }}/{{ item.key }}"
+  with_dict: "{{ named_domains }}"
+  when: item.value.dynamic == true and
+        item.value.ddns_hostname_prefixes is defined
+  # Don't fail if there are no records to store
+  failed_when: false
+
 - name: Write forward zone files
   template:
     src: forward.j2
@@ -22,6 +60,9 @@
     validate: named-checkzone {{ item.key }} %s
   with_dict: "{{ named_domains }}"
   notify: reload named
+  # Don't write zone files for pure dynamic zones
+  when: (item.value.dynamic != true) or
+        (item.value.dynamic == true and item.value.ddns_hostname_prefixes is defined)
 
 - name: Write reverse zone files
   template:
     - flags:
       skip_missing: True
   notify: reload named
+
+- name: Restore dynamic A records from temp file(s)
+  shell: "cat {{ named_tempdir.stdout }}/{{ item.key }} >> {{ named_conf_zones_path }}/{{ item.key }}"
+  with_dict: "{{ named_domains }}"
+  when: item.value.dynamic == true and
+        item.value.ddns_hostname_prefixes is defined
+  # Don't fail if there are no records to restore
+  failed_when: false
+
+# This gets rid of any cached dynamic records that we didn't just restore
+- name: Freeze, reload, thaw dynamic zone files
+  shell: "rndc freeze; rndc reload; rndc thaw"
+
+- name: Clean up dynamic A records temp dir
+  file:
+    path: "{{ named_tempdir.stdout }}"
+    state: absent