Client role
diff --git a/README.rst b/README.rst
index c417370..62aa837 100644
--- a/README.rst
+++ b/README.rst
@@ -8,28 +8,103 @@
 Sample pillars
 ==============
 
-Sample pillar installed from system package
+Server deployments
+------------------
+
+Server installed from system package
+
+.. code-block:: yaml
 
     grafana:
       server:
         enabled: true
+        admin:
+          user: admin
+          password: passwd
+        database:
+          engine: sqlite
+
+Server installed with PostgreSQL database
+
+.. code-block:: yaml
+
+    grafana:
+      server:
+        enabled: true
+        admin:
+          user: admin
+          password: passwd
         database:
           engine: postgresql
           host: localhost
           port: 5432
-        data_source:
-          metrics1:
-            engine: graphite
-            host: metrics1.domain.com
-            ssl: true
+          name: grafana
+          user: grafana
+          password: passwd
+
+Client setups
+-------------
+
+Client enforced data sources
+
+.. code-block:: yaml
+
+    grafana:
+      client:
+        enabled: true
+        server:
+          protocol: https
+          host: grafana.host
+          port: 3000
+          token: token
+        datasource:
+          graphite:
+            type: graphite
+            host: mtr01.domain.com
+            protocol: https
             port: 443
-            user: test
-          metrics2:
-            engine: elasticsearch
-            host: metrics2.domain.com
+          elasticsearch:
+            type: elasticsearch
+            host: log01.domain.com
             port: 80
-            user: test
+            user: admin
+            password: password
             index: grafana-dash
+
+Client enforced dashboards
+
+.. code-block:: yaml
+
+    grafana:
+      client:
+        enabled: true
+        server:
+          host: grafana.host
+          port: 3000
+          token: token
+        dashboard:
+          system_metrics:
+            title: "Generic system metrics"
+            style: dark
+            editable: false
+            row:
+              top:
+                title: "First row"
+
+Client enforced dashboards defined in salt-mine
+
+.. code-block:: yaml
+
+    grafana:
+      client:
+        enabled: true
+        collect_mine: true
+        server:
+          host: grafana.host
+          port: 3000
+          token: token
+
+
 Read more
 =========
 
diff --git a/grafana/client.sls b/grafana/client.sls
new file mode 100644
index 0000000..7e1e680
--- /dev/null
+++ b/grafana/client.sls
@@ -0,0 +1,38 @@
+{%- from "grafana/map.jinja" import client with context %}
+{%- if client.enabled %}
+
+/etc/salt/minion.d/_grafana.conf:
+  file.managed:
+  - source: salt://grafana/files/_grafana.conf
+  - template: jinja
+  - user: root
+  - group: root
+
+{%- for datasource_name, datasource in client.datasource.iteritems() %}
+
+grafana_client_datasource_{{ datasource_name }}:
+  grafana_datasource.present:
+  - name: {{ datasource_name }}
+  - type: {{ datasource.type }}
+  - url: http://{{ datasource.host }}:{{ datasource.get('port', 80) }}
+  {%- if datasource.access is defined %}
+  - access: proxy
+  {%- endif %}
+  {%- if datasource.user is defined %}
+  - basic_auth: true
+  - basic_auth_user: {{ datasource.user }}
+  - basic_auth_password: {{ datasource.password }}
+  {%- endif %}
+
+{%- endfor %}
+
+{%- for dashboard_name, dashboard in client.dashboard.iteritems() %}
+
+grafana_client_dashboard_{{ dashboard_name }}:
+  grafana_dashboard.present:
+  - name: {{ dashboard_name }}
+  - dashboard: {{ dashboard }}
+
+{%- endfor %}
+
+{%- endif %}
diff --git a/grafana/files/_grafana.conf b/grafana/files/_grafana.conf
new file mode 100644
index 0000000..105af23
--- /dev/null
+++ b/grafana/files/_grafana.conf
@@ -0,0 +1,8 @@
+{%- from "grafana/map.jinja" import client with context %}
+
+grafana_version: 2
+
+grafana:
+  grafana_timeout: 3
+  grafana_token: {{ client.server.token }}
+  grafana_url: 'http://{{ client.server.host }}:{{ client.server.get('port', 80) }}'
diff --git a/grafana/files/grafana.ini b/grafana/files/grafana.ini
index 5762081..dd249b4 100644
--- a/grafana/files/grafana.ini
+++ b/grafana/files/grafana.ini
@@ -25,7 +25,7 @@
 # The ip address to bind to, empty will bind to all interfaces
 http_addr = {{ server.bind.address }}
 
-# The http port  to use
+# The http port to use
 http_port = {{ server.bind.port }}
 
 # The public facing domain name used to access grafana from a browser
@@ -55,21 +55,25 @@
 [database]
 # Either "mysql", "postgres" or "sqlite3", it's your choice
 type = {% if server.database.engine == "postgresql" %}postgres{% else %}{{ server.database.engine }}{% endif %}
+{%- if server.database.engine in ["postgresql", "mysql"] %}
 host = {{ server.database.host }}:{{ server.database.port }}
 name = {{ server.database.name }}
 user = {{ server.database.user }}
 password = {{ server.database.password }}
+{%- endif %}
 
 # For "postgres" only, either "disable", "require" or "verify-full"
 ;ssl_mode = disable
 
 # For "sqlite3" only, path relative to data_path setting
-;path = grafana.db
+{%- if server.database.engine in ["postgresql"] %}
+path = grafana.db
+{%- endif %}
 
 #################################### Session ####################################
 [session]
 # Either "memory", "file", "redis", "mysql", "postgres", default is "file"
-provider = {{ server.get('session', {}).get('engine', 'file') }}
+provider = {{ server.session.engine }}
 
 # Provider config options
 # memory: not have any config yet
@@ -77,7 +81,7 @@
 # redis: config like redis server e.g. `addr=127.0.0.1:6379,pool_size=100,db=grafana`
 # mysql: go-sql-driver/mysql dsn config string, e.g. `user:password@tcp(127.0.0.1:3306)/database_name`
 # postgres: user=a password=b host=localhost port=5432 dbname=c sslmode=disable
-{%- if server.get('session', {}).get('engine', 'file') == 'redis' %}
+{%- if server.session.engine == 'redis' %}
 provider_config = addr={{ server.session.get('host', '127.0.0.1') }}:{{ server.session.get('port', 6379) }},db={{ server.session.get('db', 'grafana') }}
 {%- endif %}
 
@@ -104,10 +108,10 @@
 #################################### Security ####################################
 [security]
 # default admin user, created on startup
-;admin_user = admin
+admin_user = {{ server.admin.user }}
 
 # default admin password, can be changed before first start of grafana,  or in profile settings
-;admin_password = admin
+admin_password = {{ server.admin.password }}
 
 # used for signing
 ;secret_key = SW2YcwTIb9zpOOhoPsMm
@@ -126,21 +130,21 @@
 #################################### Users ####################################
 [users]
 # disable user signup / registration
-allow_sign_up = {{ server.get('users', {}).get('sign_up', True)|lower }}
+allow_sign_up = {{ server.allow_sign_up|lower }}
 
 # Allow non admin users to create organizations
-allow_org_create = {{ server.get('users', {}).get('org_create', True)|lower }}
+allow_org_create = {{ server.allow_org_create|lower }}
 
 # Set to true to automatically assign new users to the default organization (id 1)
 ;auto_assign_org = true
 
 # Default role new users will be automatically assigned (if disabled above is set to true)
 ;auto_assign_org_role = Viewer
-auto_assign_org_role = {{ server.get('users', {}).get('auto_assign_role', 'Viewer') }}
+auto_assign_org_role = {{ server.auto_assign_role }}
 
 #################################### Anonymous Auth ##########################
 [auth.anonymous]
-{%- if server.get('auth', {}).get('engine', None) == 'anonymous' %}
+{%- if server.auth.engine == 'anonymous' %}
 enabled = true
 
 {%- if server.auth.organization is defined %}
@@ -189,7 +193,7 @@
 
 #################################### Auth Proxy ##########################
 [auth.proxy]
-{%- if server.get('auth', {}).get('engine', None) == 'proxy' %}
+{%- if server.auth.engine == 'proxy' %}
 enabled = true
 header_name = {{ server.auth.get('header', 'X-Forwarded-User') }}
 header_property = {{ server.auth.get('header_property', 'username') }}
@@ -198,10 +202,10 @@
 
 #################################### Basic Auth ##########################
 [auth.basic]
-{%- if server.get('auth', {}).get('engine', 'basic') != 'basic' %}
-enabled = false
-{%- else %}
+{%- if server.auth.engine == 'basic' %}
 enabled = true
+{%- else %}
+enabled = false
 {%- endif %}
 
 #################################### Auth LDAP ##########################
diff --git a/grafana/init.sls b/grafana/init.sls
index ce1d045..9562a07 100644
--- a/grafana/init.sls
+++ b/grafana/init.sls
@@ -4,4 +4,7 @@
 {%- if pillar.grafana.server is defined %}
 - grafana.server
 {%- endif %}
+{%- if pillar.grafana.client is defined %}
+- grafana.client
+{%- endif %}
 {%- endif %}
diff --git a/grafana/map.jinja b/grafana/map.jinja
index d522f3b..baeab61 100644
--- a/grafana/map.jinja
+++ b/grafana/map.jinja
@@ -7,6 +7,27 @@
   bind:
     address: 0.0.0.0
     port: 3000
+  session:
+    engine: file
+  auth:
+    engine: application
+  admin:
+    user: admin
+    password: admin
+  allow_sign_up: False
+  allow_org_create: False
+  auto_assign_role: Viewer
 {%- endload %}
 
-{%- set server = salt['grains.filter_by'](base_defaults, merge=salt['pillar.get']('grafana:server')) %}
\ No newline at end of file
+{%- set server = salt['grains.filter_by'](base_defaults, merge=salt['pillar.get']('grafana:server')) %}
+
+{%- load_yaml as base_defaults %}
+Debian:
+  server:
+    host: 127.0.0.1
+    port: 3000
+  datasource: {}
+  dashboard: {}
+{%- endload %}
+
+{%- set client = salt['grains.filter_by'](base_defaults, merge=salt['pillar.get']('grafana:client')) %}