Initial commit of NSD ansible role

Change-Id: I97c6455f2513604b86156017b5b7b1d769e7bbc0
diff --git a/templates/nsd.conf.j2 b/templates/nsd.conf.j2
new file mode 100644
index 0000000..ff5b39f
--- /dev/null
+++ b/templates/nsd.conf.j2
@@ -0,0 +1,31 @@
+{#
+SPDX-FileCopyrightText: © 2020 Open Networking Foundation <support@opennetworking.org>
+SPDX-License-Identifier: Apache-2.0
+#}
+# nsd templates/nsd.conf.j2 - {{ ansible_managed }}
+
+server:
+  hide-version: yes
+
+## bind to a specific address/port
+  ip-address: {{ nsd_ip4 }}
+  ip4-only: yes
+  port: {{ nsd_port }}
+
+  server-count: 1
+  zonesdir: {{ nsd_zones_dir }}
+
+remote-control:
+  control-enable: yes
+
+# zonefiles to load
+{% for key, value in dns_zones.items() %}
+zone:
+  name: {{ key }}
+  zonefile: {{ key }}.forward
+
+zone:
+  name: {{ value.ip_range | unbound_revdns }}
+  zonefile: {{ key }}.reverse
+
+{% endfor %}
diff --git a/templates/zone.forward.j2 b/templates/zone.forward.j2
new file mode 100644
index 0000000..1a10187
--- /dev/null
+++ b/templates/zone.forward.j2
@@ -0,0 +1,49 @@
+{#
+SPDX-FileCopyrightText: © 2020 Open Networking Foundation <support@opennetworking.org>
+SPDX-License-Identifier: Apache-2.0
+#}
+;# nsd forward zone, templates/zone.forward.j2 - {{ ansible_managed }}
+
+$ORIGIN {{ item.key }}. ; default zone domain
+$TTL {{ item.ttl | default(nsd_default_ttl) }} ; default time to live
+
+@ IN SOA {{ item.value.ns | first }} admin.{{ item.key }}. (
+         {{ item.value.serial | default(ansible_date_time.epoch) }}   ; Serial, must be incremented every time you change this file
+         3600        ; Refresh [1hr]
+         600         ; Retry [10m]
+         3600        ; Expire [1hr]
+         60          ; Min TTL [1m]
+         )
+
+; NameServers
+{% for ns in item.value.ns %}
+ IN NS {{ ns }}
+{% endfor %}
+{% if item.value.a is defined %}
+
+; A records
+{% for name, ip4 in item.value.a.items() %}
+{{ name }} IN A {{ ip4 }}
+{% endfor %}
+{% endif %}
+{% if item.value.cname is defined %}
+
+; CNAME records
+{% for name, target in item.value.cname.items() %}
+{{ name }} IN CNAME {{ target }}
+{% endfor %}
+{% endif %}
+{% if item.srv is defined %}
+
+; SRV records
+{% for name, val in item.value.srv.items() %}
+{{ name }} {{ val.ttl | default(nsd_default_ttl) }} IN SRV {{ val.priority | default(10) }} {{ val.port }} {{ val.target }}
+{% endfor %}
+{% endif %}
+{% if item.value.txt is defined %}
+
+; TXT records
+{% for name, val in item.value.txt.items() %}
+{{ name }} IN TXT "{{ val }}"
+{% endfor %}
+{% endif %}
diff --git a/templates/zone.reverse.j2 b/templates/zone.reverse.j2
new file mode 100644
index 0000000..a0e5ecc
--- /dev/null
+++ b/templates/zone.reverse.j2
@@ -0,0 +1,23 @@
+{#
+SPDX-FileCopyrightText: © 2020 Open Networking Foundation <support@opennetworking.org>
+SPDX-License-Identifier: Apache-2.0
+#}
+;# nsd reverse zone, templates/zone.reverse.j2 - {{ ansible_managed }}
+
+$ORIGIN {{ item.key }}. ; default zone domain
+$TTL {{ item.value.ttl | default(nsd_default_ttl) }} ; default time to live
+
+{{ item.value.ip_range | unbound_revdns }} IN SOA {{ item.value.ns | first }} admin.{{ item.key }}. (
+         {{ item.value.serial | default(ansible_date_time.epoch) }}   ; Serial, must be incremented every time you change this file
+         3600        ; Refresh [1hr]
+         600         ; Retry [10m]
+         3600        ; Expire [1hr]
+         60          ; Min TTL [1m]
+         )
+{% if item.value.a is defined %}
+
+; PTR records
+{% for name, ip4 in item.value.a.items() %}
+{{ ip4 | ipaddr('revdns')}} IN PTR {{ name }}
+{% endfor %}
+{% endif %}