|
#!/bin/sh |
|
|
|
###### |
|
# |
|
# This script can be used to initialise databases and users in an Influx DB |
|
# installation. Most dash-led options are passed further to the influx |
|
# command-line tool. All file paths that follows the -- separator contain |
|
# user/db configurations that will be understood by this script. In these |
|
# configuration files, lines starting with a hash-sign and empty lines are |
|
# ignored. Otherwise, lines should contain a number of colon separated fields, |
|
# which are understood as follows: |
|
# |
|
# * colon separated list of databases accessible by user, empty for none |
|
# * name of user |
|
# * password, empty for auto-generated |
|
# * combination of rwx (read, write, x is for all privileges, i.e. admin rights) |
|
# |
|
# Note that leading and trailing whitespaces are removed from user and database |
|
# names automatically. Autogenerated passwords will be printed out on the |
|
# standard error. |
|
# |
|
# When called without authorisation details, this tool will automatically pick |
|
# the first administrator that it discovers to perform all further operations on |
|
# users and databases. This ensures that, when an administrator is the first |
|
# user declared and InfluxDB is configured to force authorisation, all |
|
# operations will properly succeed. |
|
# |
|
# It is possible to specify a specific binary (full path, different command) |
|
# with the -i (or --influx) option. Specifying --verbose will allow to print |
|
# out internal decisions, at the expense of printing out sensitive passwords. |
|
# |
|
###### |
|
|
|
# Eat all options so we can pass them to influx when calling it, all remaining |
|
# stuff should be file names. |
|
INFLUX="influx" |
|
OPTS="" |
|
VERBOSE=0 |
|
while [ $# -gt 0 ]; do |
|
case "$1" in |
|
--) |
|
# End of options, everything that follows will be filenames |
|
shift |
|
break |
|
;; |
|
-i|--influx) |
|
# Capture separate path to binary, just in case |
|
INFLUX="$2" |
|
shift 2 |
|
;; |
|
--verbose) |
|
VERBOSE=1 |
|
shift |
|
;; |
|
*) |
|
# All other options are supposed to take an argument (which isn't |
|
# entirely true), store them and arrange to capture them for further |
|
# invokation of influx. |
|
OPTS="${OPTS} $1 $2" |
|
shift 2 |
|
;; |
|
esac |
|
done |
|
|
|
|
|
verbose() { |
|
if [ "$VERBOSE" = "1" ]; then printf "%s\n" "$*" 1>&2; fi |
|
} |
|
|
|
warn() { |
|
printf "%s\n" "$*" 1>&2 |
|
} |
|
|
|
callinflux() { |
|
verbose "InfluxQL (${OPTS}): $1" |
|
${INFLUX} ${OPTS} -execute "$1" |
|
} |
|
|
|
|
|
for fname in "$@"; do |
|
DBS="" |
|
# See http://mywiki.wooledge.org/BashFAQ/024 for the loop... |
|
while IFS= read -r line; do |
|
line=$(echo "${line}" | sed '/^[[:space:]]*$/d' | sed '/^[[:space:]]*#/d') |
|
if [ -n "${line}" ]; then |
|
dbs=$(echo -e "${line}"|cut -d: -f1) |
|
user=$(echo -e "${line}"|cut -d: -f2) |
|
pass=$(echo -e "${line}"|cut -d: -f3) |
|
access=$(echo -e "${line}"|cut -d: -f4) |
|
|
|
# Create, amend the user and take care of admin privieges early. |
|
user=$(echo -e "${user}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//') |
|
|
|
if [ -z "${pass}" ]; then |
|
pass=$(strings /dev/urandom | grep -o '[[:alnum:]]' | head -n 16 | tr -d '\n') |
|
warn "Generated password '$pass' for $user" |
|
fi |
|
|
|
if [ -n "${user}" ]; then |
|
# Create the user if it does not already exist. |
|
already=$(callinflux "SHOW USERS;" | tail -n +3 | grep ${user}) |
|
if [ -z "${already}" ]; then |
|
admin=$(echo "${access}" | grep x) |
|
# Check privileges (represented by an x) |
|
if [ -z "${admin}" ]; then |
|
verbose "Creating user ${user}" |
|
callinflux "CREATE USER \"${user}\" WITH PASSWORD '${pass}';" |
|
else |
|
verbose "Creating administrator ${user}" |
|
callinflux "CREATE USER \"${user}\" WITH PASSWORD '${pass}' WITH ALL PRIVILEGES;" |
|
|
|
hasauth=$(echo -e "${OPTS}"|grep '\-username') |
|
if [ -z "${hasauth}" ]; then |
|
verbose "Automatically using ${user} as an administrator for all further calls!" |
|
OPTS="${OPTS} -username ${user} -password ${pass}" |
|
fi |
|
fi |
|
else |
|
verbose "Amending password for ${user}" |
|
callinflux "SET PASSWORD FOR \"${user}\" = '${pass}';" |
|
admin=$(echo "${access}" | grep x) |
|
already=$(callinflux "SHOW USERS;" | tail -n +3 | grep ${user} | grep true) |
|
if [ -z "${admin}" -a -n "${already}" ]; then |
|
verbose "Revoking privileges for ${user}" |
|
callinflux "REVOKE ALL PRIVILEGES FROM \"${user}\";" |
|
fi |
|
if [ -n "${admin}" -a -z "${already}" ]; then |
|
verbose "Granting privileges for ${user}" |
|
callinflux "GRANT ALL PRIVILEGES TO \"${user}\";" |
|
fi |
|
fi |
|
fi |
|
|
|
# Parse the list of databases, separated by comas |
|
for db in $(echo "${dbs}" | tr "," "\n"); do |
|
db=$(echo -e "${db}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//') |
|
if [ -n "${db}" ]; then |
|
# Create the database if it does not already exist. |
|
already=$(callinflux "SHOW DATABASES;" | tail -n +3 | grep ${db}) |
|
if [ -z "${already}" ]; then |
|
verbose "Creating database ${db}" |
|
callinflux "CREATE DATABASE ${db};" |
|
else |
|
verbose "Database ${db} already exists" |
|
fi |
|
|
|
# Keep record of databases specified in file |
|
already=$(echo ${DBS}|grep ${db}) |
|
if [ -z "${already}" ]; then |
|
DBS="${DBS} ${db}" |
|
fi |
|
|
|
# Grant R/W privileges to user. |
|
read=$(echo "${access}" | grep r) |
|
write=$(echo "${access}" | grep w) |
|
if [ -n "${read}" ] && [ -n "${write}" ]; then |
|
verbose "Granting all access to ${db} for ${user}" |
|
callinflux "GRANT ALL ON \"${db}\" TO \"${user}\";" |
|
else |
|
if [ -n "${read}" ]; then |
|
verbose "Granting read access to ${db} for ${user}" |
|
callinflux "GRANT READ ON \"${db}\" TO \"${user}\";" |
|
fi |
|
if [ -n "${write}" ]; then |
|
verbose "Granting write access to ${db} for ${user}" |
|
callinflux "GRANT WRITE ON \"${db}\" TO \"${user}\";" |
|
fi |
|
fi |
|
fi |
|
done |
|
fi |
|
done < ${fname} |
|
done |