Merge pull request #3 from thouveng/add-admin-user

Configure an admin user
diff --git a/README.rst b/README.rst
index c43b53c..48a494f 100644
--- a/README.rst
+++ b/README.rst
@@ -40,6 +40,83 @@
               key_file: /etc/influxdb/ssl/key.pem
               cert_file: /etc/influxdb/ssl/cert.pem
 
+Single-node influxdb with an admin user:
+
+.. code-block:: yaml
+
+    influxdb:
+      server:
+        enabled: true
+        http:
+          enabled: true
+          bind:
+            address: 0.0.0.0
+            port: 8086
+        admin:
+          enabled: true
+          bind:
+            address: 0.0.0.0
+            port: 8083
+          user:
+            enabled: true
+            name: root
+            password: secret
+
+Single-node influxdb with new users:
+
+.. code-block:: yaml
+
+    influxdb:
+      server:
+        user:
+          user1:
+            enabled: true
+            admin: true
+            name: username1
+            password: keepsecret1
+          user2:
+            enabled: true
+            admin: false
+            name: username2
+            password: keepsecret2
+
+Single-node influxdb with new databases:
+
+.. code-block:: yaml
+
+    influxdb:
+      server:
+        database:
+          mydb1:
+            enabled: true
+            name: mydb1
+          mydb2:
+            enabled: true
+            name: mydb2
+
+Here is how to manage grants on database:
+
+.. code-block:: yaml
+
+    influxdb:
+      server:
+        grant:
+          username1_mydb1:
+            enabled: true
+            user: username1
+            database: mydb1
+            privilege: all
+          username2_mydb1:
+            enabled: true
+            user: username2
+            database: mydb1
+            privilege: read
+          username2_mydb2:
+            enabled: true
+            user: username2
+            database: mydb2
+            privilege: write
+
 InfluxDB relay:
 
 .. code-block:: yaml
diff --git a/influxdb/files/influxdb.conf b/influxdb/files/influxdb.conf
index cdd3bd9..c569239 100644
--- a/influxdb/files/influxdb.conf
+++ b/influxdb/files/influxdb.conf
@@ -187,7 +187,11 @@
 [http]
   enabled = true
   bind-address = "{{ server.http.bind.address }}:{{ server.http.bind.port }}"
+  {%- if server.admin.get('user', {}).get('enabled', false) %}
+  auth-enabled = true
+  {%- else %}
   auth-enabled = false
+  {%- endif %}
   log-enabled = true
   write-tracing = false
   pprof-enabled = false
diff --git a/influxdb/server.sls b/influxdb/server.sls
index 06643b5..c0f0ea6 100644
--- a/influxdb/server.sls
+++ b/influxdb/server.sls
@@ -25,8 +25,76 @@
   service.running:
   - enable: true
   - name: {{ server.service }}
+  # This delay is needed before being able to send data to server to create
+  # users and databases.
+  - init_delay: 5
   - watch:
     - file: influxdb_config
     - file: influxdb_default
 
+{% set url_for_query = "http://{}:{}/query".format(server.http.bind.address, server.http.bind.port) %}
+{% set admin_created = false %}
+
+{%- if server.admin.get('user', {}).get('enabled', false) %}
+  {% set query_create_admin = "--data-urlencode \"q=CREATE USER {} WITH PASSWORD '{}' WITH ALL PRIVILEGES\"".format(server.admin.user.name, server.admin.user.password) %}
+  {% set admin_url = "http://{}:{}/query?u={}&p={}".format(server.http.bind.address, server.http.bind.port, server.admin.user.name, server.admin.user.password) %}
+influxdb_create_admin:
+  cmd.run:
+  - name: curl -f -S -POST "{{ url_for_query }}" {{ query_create_admin }} || curl -f -S -POST "{{ admin_url }}" {{ query_create_admin }}
+  - require:
+    - service: influxdb_service
+  {% set url_for_query = admin_url %}
+  {% set admin_created = true %}
+{%- endif %}
+
+# An admin must exist before creating others users
+{%- if admin_created %}
+  {%- for user_name, user in server.get('user', {}).iteritems() %}
+    {%- if user.get('enabled', false) %}
+      {%- if user.get('admin', false) %}
+        {% set query_create_user = "--data-urlencode \"q=CREATE USER {} WITH PASSWORD '{}' WITH ALL PRIVILEGES\"".format(user.name, user.password) %}
+      {%- else %}
+        {% set query_create_user = "--data-urlencode \"q=CREATE USER {} WITH PASSWORD '{}'\"".format(user.name, user.password) %}
+      {%- endif %}
+influxdb_create_user_{{user.name}}:
+  cmd.run:
+    - name: curl -f -S -POST "{{ url_for_query }}" {{ query_create_user }}
+    - require:
+      - cmd: influxdb_create_admin
+    # TODO: manage user deletion
+    {%- endif %}
+  {%- endfor %}
+{%- endif %}
+
+{%- for db_name, db in server.get('database', {}).iteritems() %}
+  {%- if db.get('enabled', false) %}
+    {% set query_create_db = "--data-urlencode \"q=CREATE DATABASE {}\"".format(db.name) %}
+influxdb_create_db_{{db.name}}:
+  cmd.run:
+    - name: curl -f -S -POST "{{ url_for_query }}" {{ query_create_db }}
+    {%- if admin_created %}
+    - require:
+      - cmd: influxdb_create_admin
+    {%- endif %}
+  # TODO: manage database deletion
+  {%- endif %}
+{%- endfor %}
+
+# An admin must exist to manage grants, otherwise there is no user.
+{%- if admin_created %}
+{%- for grant_name, grant in server.get('grant', {}).iteritems() %}
+  {%- if grant.get('enabled', false) %}
+    {% set query_grant_user_access = "--data-urlencode \"q=GRANT {} ON {} TO {}\"".format(grant.privilege, grant.database, grant.user) %}
+influxdb_grant_{{grant_name}}:
+  cmd.run:
+    - name: curl -f -S -POST "{{ url_for_query }}" {{ query_grant_user_access }}
+    - require:
+      - cmd: influxdb_create_db_{{grant.database}}
+      - cmd: influxdb_create_user_{{grant.user}}
+      - cmd: influxdb_create_admin
+    # TODO: manage grant deletion (if needed)
+  {%- endif %}
+{%- endfor %}
+{%- endif %}
+
 {%- endif %}