Merge pull request #2 from salt-formulas/control

Allow definition of controls
diff --git a/README.rst b/README.rst
index a59b3b5..21a0f8b 100644
--- a/README.rst
+++ b/README.rst
@@ -8,6 +8,9 @@
 Sample pillars
 ==============
 
+Server
+------
+
 .. code-block:: yaml
 
     bind:
@@ -21,6 +24,16 @@
           8.8.8.8:
             keys:
               - keyname
+        control:
+          local:
+            enabled: true
+            bind:
+              address: 127.0.0.1
+              port: 953
+            allow:
+              - 127.0.0.1
+            keys:
+              - xyz
         zone:
           sub.domain.com:
             ttl: 86400
@@ -50,6 +63,34 @@
           hosts:
             - localhost
 
+You can use following command to generate key:
+
+.. code-block:: bash
+
+    dnssec-keygen -a HMAC-SHA512 -b 512 -n HOST -r /dev/urandom mykey
+
+Client
+------
+
+.. code-block:: yaml
+
+    bind:
+      client:
+        enabled: true
+        option:
+          default:
+            server: localhost
+            port: 953
+            key: keyname
+        key:
+          keyname:
+            secret: xyz
+            algorithm: hmac-sha512
+        server:
+          8.8.8.8:
+            keys:
+              - keyname
+
 Read more
 =========
 
diff --git a/bind/client.sls b/bind/client.sls
new file mode 100644
index 0000000..b55d5d4
--- /dev/null
+++ b/bind/client.sls
@@ -0,0 +1,19 @@
+{%- from "bind/map.jinja" import client with context %}
+{%- if client.get('enabled', True) %}
+
+bind_client_packages:
+  pkg.installed:
+  - pkgs: {{ client.pkgs }}
+
+bind_rndc_config:
+  file.managed:
+  - name: {{ client.rndc_config }}
+  - source: 'salt://bind/files/rndc.conf'
+  - template: jinja
+  - user: root
+  - group: root
+  - mode: 640
+  - require:
+    - pkg: bind_client_packages
+
+{%- endif %}
diff --git a/bind/files/_keys.conf b/bind/files/_keys.conf
new file mode 100644
index 0000000..c609194
--- /dev/null
+++ b/bind/files/_keys.conf
@@ -0,0 +1,10 @@
+{%- for keyname, key in _keys.iteritems() %}
+key "{{ keyname }}" {
+    algorithm {{ key.algorithm }};
+    secret "{{ key.secret }}";
+};
+{%- endfor %}
+
+{#-
+  vim: syntax=jinja
+#}
diff --git a/bind/files/_servers.conf b/bind/files/_servers.conf
new file mode 100644
index 0000000..c33903b
--- /dev/null
+++ b/bind/files/_servers.conf
@@ -0,0 +1,15 @@
+{%- for serverip, server in _servers.iteritems() %}
+server {{ serverip }} {
+    {%- if server.get('keys', None) %}
+    keys {
+        {%- for key in server.get('keys') %}
+        {{ key }};
+        {%- endfor %}
+    };
+    {%- endif %}
+};
+{%- endfor %}
+
+{#-
+  vim: syntax=jinja
+#}
diff --git a/bind/files/named.conf.local b/bind/files/named.conf.local
index b9017f8..9f3e0c1 100644
--- a/bind/files/named.conf.local
+++ b/bind/files/named.conf.local
@@ -28,24 +28,33 @@
 
 {%- endfor %}
 
-{%- for keyname, key in server.get('key', {}).iteritems() %}
-key "{{ keyname }}" {
-    algorithm {{ key.algorithm }};
-    secret "{{ key.secret }}";
-};
-{%- endfor %}
+{%- set _keys = server.get('key', {}) %}
+{%- include "bind/files/_keys.conf" %}
 
-{%- for serverip, server in server.get('server', {}).iteritems() %}
-server {{ serverip }} {
-    {%- if server.get('keys', None) %}
+{%- set _servers = server.get('server', {}) %}
+{%- include "bind/files/_servers.conf" %}
+
+{%- if server.get('control') %}
+controls {
+    {%- for name, control in server.control.iteritems() if control.get('enabled', True) %}
+    inet {{ control.get('bind', {}).get('address', '127.0.0.1') }} port {{ control.get('bind', {}).get('port', 953) }}
+    {%- if control.get('allow') %}
+    allow {
+        {%- for allow in control.allow %}
+        {{ allow }};
+        {%- endfor %}
+    }
+    {%- endif %}
+    {%- if control.get('keys') %}
     keys {
-        {%- for key in server.get('keys') %}
+        {%- for key in control.get('keys') %}
         {{ key }};
         {%- endfor %}
-    };
-    {%- endif %}
+    }
+    {%- endif %};
+    {%- endfor %}
 };
-{%- endfor %}
+{%- endif %}
 
 {#-
   vim: syntax=jinja
diff --git a/bind/files/rndc.conf b/bind/files/rndc.conf
new file mode 100644
index 0000000..f61d832
--- /dev/null
+++ b/bind/files/rndc.conf
@@ -0,0 +1,24 @@
+{%- from "bind/map.jinja" import client with context -%}
+{%- if client.get('rndc_key') %}
+include "{{ client.rndc_key }}";
+{%- endif %}
+
+{%- if client.get('option') %}
+options {
+    {%- if client.option.get('default') %}
+        {%- for k, v in client.option.default.iteritems() %}
+    default-{{ k }} {{ v }};
+        {%- endfor %}
+    {%- endif %}
+};
+{%- endif %}
+
+{%- set _keys = client.get('key', {}) %}
+{%- include "bind/files/_keys.conf" %}
+
+{%- set _servers = client.get('server', {}) %}
+{%- include "bind/files/_servers.conf" %}
+
+{#-
+  vim: syntax=jinja
+#}
diff --git a/bind/init.sls b/bind/init.sls
index b9a143c..99b99f0 100644
--- a/bind/init.sls
+++ b/bind/init.sls
@@ -3,3 +3,6 @@
 {%- if pillar.bind.server is defined %}
 - bind.server
 {%- endif %}
+{%- if pillar.bind.client is defined %}
+- bind.client
+{%- endif %}
diff --git a/bind/map.jinja b/bind/map.jinja
index b4e261c..b072011 100644
--- a/bind/map.jinja
+++ b/bind/map.jinja
@@ -21,3 +21,11 @@
     'group': 'named'
   },
 }, merge=salt['pillar.get']('bind:server')) %}
+
+{%- set client = salt['grains.filter_by']({
+  'Debian': {
+    'pkgs': ['bind9utils'],
+    'rndc_config': '/etc/rndc.conf',
+    'rndc_key': '/etc/bind/rndc.key',
+  },
+}, merge=salt['pillar.get']('bind:client')) %}
diff --git a/bind/meta/sphinx.yml b/bind/meta/sphinx.yml
index e4ab6df..1276b19 100644
--- a/bind/meta/sphinx.yml
+++ b/bind/meta/sphinx.yml
@@ -7,3 +7,8 @@
       name: server
       param: {}
   {%- endif %}
+  {%- if pillar.bind.client is defined %}
+    client:
+      name: client
+      param: {}
+  {%- endif %}
diff --git a/metadata/service/client.yml b/metadata/service/client.yml
new file mode 100644
index 0000000..3060e03
--- /dev/null
+++ b/metadata/service/client.yml
@@ -0,0 +1,6 @@
+applications:
+- bind
+parameters:
+  bind:
+    client:
+      enabled: true