From f616965443ccd67fde703ff9b4b085f09c8703b7 Mon Sep 17 00:00:00 2001 From: Simon Pasquier Date: Mon, 17 Jul 2017 14:04:19 +0200 Subject: [PATCH] Add client role The client role is responsible for provisioning the users, databases and privileges. It is required when running InfluxDB in a container because the deployment of InfluxDB and the provisioning phase are decoupled. Non-containerized deployments are left unchanged with the provisioning managed by the server state. Change-Id: I7c9a05f2109f76aadf84953374c740a865d59106 --- .kitchen.yml | 5 +++ README.rst | 34 +++++++++++++++ influxdb/client.sls | 83 +++++++++++++++++++++++++++++++++++++ influxdb/init.sls | 9 +++- influxdb/map.jinja | 5 +++ metadata/service/client.yml | 6 +++ tests/pillar/client.sls | 41 ++++++++++++++++++ 7 files changed, 181 insertions(+), 2 deletions(-) create mode 100644 influxdb/client.sls create mode 100644 metadata/service/client.yml create mode 100644 tests/pillar/client.sls diff --git a/.kitchen.yml b/.kitchen.yml index 2e338c4..ce9948e 100644 --- a/.kitchen.yml +++ b/.kitchen.yml @@ -44,6 +44,11 @@ platforms: suites: + - name: client + provisioner: + pillars-from-files: + influxdb.sls: tests/pillar/client.sls + - name: cluster provisioner: pillars-from-files: diff --git a/README.rst b/README.rst index 60d3cb8..c79788f 100644 --- a/README.rst +++ b/README.rst @@ -230,6 +230,40 @@ Deploy influxdb apt repository (using linux formula): source: 'deb https://repos.influxdata.com/${linux:system:os} ${linux:system:dist} stable' key_url: 'https://repos.influxdata.com/influxdb.key' +InfluxDB client for configuring databases, users and retention policies: + +.. code-block:: yaml + + influxdb: + client: + enabled: true + server: + protocol: http + host: 127.0.0.1 + port: 8086 + user: admin + password: foobar + user: + user1: + enabled: true + admin: true + name: username1 + database: + mydb1: + enabled: true + name: mydb1 + retention_policy: + - name: rp_db1 + duration: 30d + replication: 1 + is_default: true + grant: + username1_mydb1: + enabled: true + user: username1 + database: mydb1 + privilege: all + Read more ========= diff --git a/influxdb/client.sls b/influxdb/client.sls new file mode 100644 index 0000000..f312531 --- /dev/null +++ b/influxdb/client.sls @@ -0,0 +1,83 @@ +{%- from "influxdb/map.jinja" import client with context %} + +{%- if client.get('enabled') %} + +{%- set curl_command = 'curl' %} +{%- if grains.get('noservices') %} +{%- set curl_command = 'true ' + curl_command %} +{%- endif %} + +{%- set noauth_url = "{}://{}:{}/query".format(client.server.protocol, client.server.host, client.server.port) %} +{%- set auth_url = "{}?u={}&p={}".format(noauth_url, client.server.user, client.server.password) %} + +{# Create the admin user (this is only required on the first run) #} +{% set create_admin_query = "--data-urlencode \"q=CREATE USER {} WITH PASSWORD '{}' WITH ALL PRIVILEGES\"".format(client.server.user, client.server.password) %} +influxdb_create_admin: + cmd.run: + - name: {{ curl_command }} -f -S -POST "{{ noauth_url }}" {{ create_admin_query }} || {{ curl_command }} -f -S -POST "{{ auth_url }}" {{ create_admin_query }} + +{# Create the regular users #} +{%- for user_name, user in client.get('user', {}).iteritems() %} + {%- if user.get('enabled', False) %} + {%- if user.get('admin', False) %} + {% set create_user_query = "--data-urlencode \"q=CREATE USER {} WITH PASSWORD '{}' WITH ALL PRIVILEGES\"".format(user.name, user.password) %} + {%- else %} + {% set create_user_query = "--data-urlencode \"q=CREATE USER {} WITH PASSWORD '{}'\"".format(user.name, user.password) %} + {%- endif %} +influxdb_create_user_{{user.name}}: + cmd.run: + - name: {{ curl_command }} -f -S -POST "{{ auth_url }}" {{ create_user_query }} + - require: + - cmd: influxdb_create_admin + {%- endif %} +{%- endfor %} + +{# Create the databases #} +{%- for db_name, db in client.get('database', {}).iteritems() %} + {%- if db.get('enabled', False) %} + {% set create_db_query = "--data-urlencode \"q=CREATE DATABASE {}\"".format(db.name) %} +influxdb_create_db_{{ db.name }}: + cmd.run: + - name: {{ curl_command }} -f -S -POST "{{ auth_url }}" {{ create_db_query }} + - require: + - cmd: influxdb_create_admin + + {% for rp in db.get('retention_policy', []) %} + {% set rp_name = rp.get('name', 'autogen') %} + {% if rp.get('is_default') %} + {% set is_default = 'DEFAULT' %} + {% else %} + {% set is_default = '' %} + {% endif %} + {% set duration = rp.get('duration', 'INF') %} + {% set replication = rp.get('replication', '1') %} + {% if rp.get('shard_duration') %} + {% set shard_duration = 'SHARD DURATION {}'.format(rp.shard_duration) %} + {% else %} + {% set shard_duration = '' %} + {% endif %} + {% set query_retention_policy = 'RETENTION POLICY {} ON {} DURATION {} REPLICATION {} {} {}'.format( + rp_name, db.name, duration, replication, shard_duration, is_default) + %} +influxdb_retention_policy_{{db.name}}_{{ rp_name }}: + cmd.run: + - name: {{ curl_command }} -s -S -POST "{{ auth_url }}" --data-urlencode "q=CREATE {{ query_retention_policy }}"|grep -v "policy already exists" || {{ curl_command }} -s -S -POST "{{ auth_url }}" --data-urlencode "q=ALTER {{ query_retention_policy }}" + - require: + - cmd: influxdb_create_db_{{db.name}} + {%- endfor %} + {%- endif %} +{%- endfor %} + +{%- for grant_name, grant in client.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_command }} -f -S -POST "{{ auth_url }}" {{ query_grant_user_access }} + - require: + - cmd: influxdb_create_db_{{ grant.database }} + - cmd: influxdb_create_user_{{ grant.user }} + {%- endif %} +{%- endfor %} + +{%- endif %} diff --git a/influxdb/init.sls b/influxdb/init.sls index 9d0eeb9..a878715 100644 --- a/influxdb/init.sls +++ b/influxdb/init.sls @@ -1,4 +1,9 @@ -{% if pillar.influxdb.server is defined %} +{%- if pillar.influxdb is defined %} include: +{%- if pillar.influxdb.server is defined %} - influxdb.server -{% endif %} +{%- endif %} +{%- if pillar.influxdb.client is defined %} +- influxdb.client +{%- endif %} +{%- endif %} diff --git a/influxdb/map.jinja b/influxdb/map.jinja index c9a0419..c059cf4 100644 --- a/influxdb/map.jinja +++ b/influxdb/map.jinja @@ -41,3 +41,8 @@ default: 'dropped_points_percentage': 5, }, }, grain='os_family', merge=salt['pillar.get']('influxdb:monitoring')) %} + +{%- set client = salt['grains.filter_by']({ + 'default': { + }, +}, merge=salt['pillar.get']('influxdb:client')) %} diff --git a/metadata/service/client.yml b/metadata/service/client.yml new file mode 100644 index 0000000..d64d7a1 --- /dev/null +++ b/metadata/service/client.yml @@ -0,0 +1,6 @@ +applications: +- influxdb +parameters: + influxdb: + client: + enabled: true diff --git a/tests/pillar/client.sls b/tests/pillar/client.sls new file mode 100644 index 0000000..5d1f0d2 --- /dev/null +++ b/tests/pillar/client.sls @@ -0,0 +1,41 @@ +influxdb: + client: + enabled: true + server: + protocol: http + host: 127.0.0.1 + port: 8086 + user: admin + password: foobar + user: + user1: + enabled: true + admin: true + name: username1 + password: secret + database: + mydb1: + enabled: true + name: mydb1 + retention_policy: + - name: rp_db1 + duration: 30d + replication: 1 + is_default: true + - name: rp_db2 + duration: 365d + replication: 1 + mydb2: + enabled: true + name: mydb2 + grant: + username1_mydb1: + enabled: true + user: username1 + database: mydb1 + privilege: all + username1_mydb2: + enabled: true + user: username1 + database: mydb2 + privilege: read -- 2.32.7