mirror of
https://github.com/vale981/phoebe
synced 2025-03-04 17:31:41 -05:00
New service: InfluxDB
This commit is contained in:
parent
b1ed1aff0f
commit
c45f05c96c
7 changed files with 326 additions and 0 deletions
|
@ -21,6 +21,10 @@ Module List
|
|||
Start and manage PostgreSQL, including automatic user and database
|
||||
creation.
|
||||
|
||||
* `phoebe.services.influxdb`:
|
||||
|
||||
Start and manage InfluxDB, including users and databases.
|
||||
|
||||
* `phoebe.services.rails`:
|
||||
|
||||
Configure and manage Ruby on Rails applications. Includes a
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
{
|
||||
imports = [
|
||||
./influxdb
|
||||
./postgresql
|
||||
];
|
||||
}
|
||||
|
|
23
modules/services/databases/influxdb/createdb.sh
Executable file
23
modules/services/databases/influxdb/createdb.sh
Executable file
|
@ -0,0 +1,23 @@
|
|||
#!/bin/sh
|
||||
|
||||
################################################################################
|
||||
set -e
|
||||
set -u
|
||||
|
||||
################################################################################
|
||||
if [ $# -ne 1 ]; then
|
||||
>&2 echo "ERROR: must give database name."
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
# List all databases:
|
||||
databases() {
|
||||
influx -format csv -execute "show databases" | \
|
||||
grep -E '^databases,' | sed 's/^databases,//'
|
||||
}
|
||||
|
||||
################################################################################
|
||||
if ! (databases | grep --fixed-strings --line-regexp --quiet "$1"); then
|
||||
influx -execute "create database $1"
|
||||
fi
|
40
modules/services/databases/influxdb/creategrant.sh
Executable file
40
modules/services/databases/influxdb/creategrant.sh
Executable file
|
@ -0,0 +1,40 @@
|
|||
#!/bin/sh
|
||||
|
||||
################################################################################
|
||||
set -e
|
||||
set -u
|
||||
|
||||
################################################################################
|
||||
if [ $# -ne 3 ]; then
|
||||
>&2 echo "Usage: creategrant.sh user database privilege"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
name=$(echo "$1" | tr --complement --delete "a-zA-Z0-9_-")
|
||||
db=$(echo "$2" | tr --complement --delete "a-zA-Z0-9_-")
|
||||
priv=$3
|
||||
|
||||
################################################################################
|
||||
privileges() {
|
||||
influx -format csv -execute "SHOW GRANTS FOR \"${name}\"" | \
|
||||
grep -v "^database,privilege$" | \
|
||||
sed 's/^/,/' # Add for anchoring.
|
||||
}
|
||||
|
||||
################################################################################
|
||||
privilege_for_db() {
|
||||
privileges | \
|
||||
grep --fixed-strings ",${db}," | \
|
||||
head -n 1 | sed -e 's/^,//' -e 's/ .*$//' | cut -d, -f2
|
||||
}
|
||||
|
||||
################################################################################
|
||||
match=$(privilege_for_db)
|
||||
|
||||
if [ -z "$match" ]; then
|
||||
influx -execute "GRANT ${priv} ON \"${db}\" TO \"${name}\""
|
||||
elif [ "$priv" != "$match" ]; then
|
||||
influx -execute "REVOKE ALL ON \"${db}\" FROM \"${name}\""
|
||||
influx -execute "GRANT ${priv} ON \"${db}\" TO \"${name}\""
|
||||
fi
|
61
modules/services/databases/influxdb/createuser.sh
Executable file
61
modules/services/databases/influxdb/createuser.sh
Executable file
|
@ -0,0 +1,61 @@
|
|||
#!/bin/sh
|
||||
|
||||
################################################################################
|
||||
set -e
|
||||
set -u
|
||||
|
||||
################################################################################
|
||||
if [ $# -ne 3 ]; then
|
||||
>&2 echo "ERROR: Usage: createuser.sh name file isadmin"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
name=$(echo "$1" | tr --complement --delete "a-zA-Z0-9_-")
|
||||
pass=$(head -n 1 "$2" | tr --delete "'")
|
||||
isadmin=$3
|
||||
|
||||
################################################################################
|
||||
# List all users:
|
||||
users() {
|
||||
influx -format csv -execute "show users" | \
|
||||
grep -Ev '^user,admin$' | \
|
||||
sed 's/^/,/' # Allow searches to be anchored.
|
||||
}
|
||||
|
||||
################################################################################
|
||||
find_user() {
|
||||
user=$1
|
||||
|
||||
users | \
|
||||
grep --fixed-strings --ignore-case ",${user}," | \
|
||||
head -n 1 | \
|
||||
sed 's/^,//'
|
||||
}
|
||||
|
||||
################################################################################
|
||||
match=$(find_user "$name")
|
||||
|
||||
if [ -z "${match}" ]; then
|
||||
if [ "$isadmin" -eq 1 ]; then
|
||||
# Need to create admin user. Needs to be a separate branch
|
||||
# because this is the only query allowed when authentication is
|
||||
# enabled but there are no users yet.
|
||||
match="${name},true"
|
||||
influx -execute "CREATE USER ${name} WITH PASSWORD '${pass}' WITH ALL PRIVILEGES"
|
||||
else
|
||||
# Need to create user a regular user.
|
||||
match="${name},false"
|
||||
influx -execute "CREATE USER ${name} WITH PASSWORD '${pass}'"
|
||||
fi
|
||||
else
|
||||
# Need to update password:
|
||||
influx -execute "SET PASSWORD FOR \"${name}\" = '${pass}'"
|
||||
fi
|
||||
|
||||
# Double check the access level:
|
||||
if [ "$isadmin" -eq 1 ] && [ "$match" = "${name},false" ]; then
|
||||
influx -execute "GRANT ALL PRIVILEGES TO \"${name}\""
|
||||
elif [ "$isadmin" -eq 0 ] && [ "$match" = "${name},true" ]; then
|
||||
influx -execute "REVOKE ALL PRIVILEGES FROM \"${name}\""
|
||||
fi
|
176
modules/services/databases/influxdb/default.nix
Normal file
176
modules/services/databases/influxdb/default.nix
Normal file
|
@ -0,0 +1,176 @@
|
|||
# Configure InfluxDB:
|
||||
{ config, lib, pkgs, ...}:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.phoebe.services.influxdb;
|
||||
plib = config.phoebe.lib;
|
||||
scripts = import ./scripts.nix { inherit config lib pkgs; };
|
||||
usernameRe = "^[a-zA-Z0-9_-]+$";
|
||||
|
||||
##############################################################################
|
||||
# User accounts:
|
||||
account = { name, ... }: {
|
||||
options = {
|
||||
name = mkOption {
|
||||
type = types.strMatching usernameRe;
|
||||
example = "jdoe";
|
||||
description = "Username for the accout.";
|
||||
};
|
||||
|
||||
passwordFile = mkOption {
|
||||
type = types.path;
|
||||
example = "/run/keys/influxdb-jdoe";
|
||||
description = ''
|
||||
File containing the account password. Note that the
|
||||
password may not contain single quotes. If any single
|
||||
quotes are present they will be silently removed.
|
||||
'';
|
||||
};
|
||||
|
||||
isAdmin = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
example = true;
|
||||
description = "Whether to grant full admin rights to this user.";
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
name = mkDefault name;
|
||||
};
|
||||
};
|
||||
|
||||
##############################################################################
|
||||
# Privileges:
|
||||
privilege = { name, ...}: {
|
||||
options = {
|
||||
user = mkOption {
|
||||
type = types.strMatching usernameRe;
|
||||
example = "jdoe";
|
||||
description = "User to grant privileges to.";
|
||||
};
|
||||
|
||||
access = mkOption {
|
||||
type = types.enum [ "READ" "WRITE" "ALL" ];
|
||||
example = "read";
|
||||
description = "Grant privilege. One of READ, WRITE, or ALL.";
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
user = mkDefault name;
|
||||
};
|
||||
};
|
||||
|
||||
##############################################################################
|
||||
# Databases:
|
||||
database = { name, ... }: {
|
||||
options = {
|
||||
name = mkOption {
|
||||
type = types.strMatching usernameRe;
|
||||
example = "my_database";
|
||||
description = "Database name.";
|
||||
};
|
||||
|
||||
privileges = mkOption {
|
||||
type = types.attrsOf (types.submodule privilege);
|
||||
default = { };
|
||||
description = "Privileges to grant for this database.";
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
name = mkDefault name;
|
||||
};
|
||||
};
|
||||
|
||||
##############################################################################
|
||||
# Create missing users:
|
||||
createuser = name: file: isadmin: ''
|
||||
${scripts}/bin/createuser.sh "${name}" "${file}" "${toString isadmin}"
|
||||
'';
|
||||
|
||||
##############################################################################
|
||||
# Create a missing database:
|
||||
createdb = database: ''
|
||||
${scripts}/bin/createdb.sh "${database.name}"
|
||||
${concatMapStringsSep "\n" (p: creategrant p.user database.name p.access)
|
||||
(attrValues database.privileges)}
|
||||
'';
|
||||
|
||||
##############################################################################
|
||||
# Create missing grants:
|
||||
creategrant = name: database: priv:
|
||||
optionalString (cfg.accounts ? "${name}") ''
|
||||
${scripts}/bin/creategrant.sh "${name}" "${database}" "${priv}"
|
||||
'';
|
||||
|
||||
##############################################################################
|
||||
# A list of services that need to be waited on for keys:
|
||||
keyservices =
|
||||
optionals cfg.auth.enable (plib.keyService cfg.superuser.passwordFile) ++
|
||||
concatMap (a: plib.keyService a.passwordFile) (attrValues cfg.accounts);
|
||||
|
||||
in
|
||||
{
|
||||
#### Interface:
|
||||
options.phoebe.services.influxdb = {
|
||||
enable = mkEnableOption "InfluxDB";
|
||||
auth.enable = mkEnableOption "Authentication.";
|
||||
|
||||
superuser.name = mkOption {
|
||||
type = types.strMatching usernameRe;
|
||||
default = config.services.influxdb.user;
|
||||
example = "root";
|
||||
description = "The name of the InfluxDB internal admin user.";
|
||||
};
|
||||
|
||||
superuser.passwordFile = mkOption {
|
||||
type = types.path;
|
||||
example = "/run/keys/influxdb-superuser";
|
||||
description = "File holding the InfluxDB internal admin password.";
|
||||
};
|
||||
|
||||
accounts = mkOption {
|
||||
type = types.attrsOf (types.submodule account);
|
||||
default = { };
|
||||
description = "User accounts.";
|
||||
};
|
||||
|
||||
databases = mkOption {
|
||||
type = types.attrsOf (types.submodule database);
|
||||
default = { };
|
||||
description = "Databases to create.";
|
||||
};
|
||||
};
|
||||
|
||||
#### Implementation:
|
||||
config = mkIf cfg.enable {
|
||||
services.influxdb.enable = true;
|
||||
services.influxdb.extraConfig.http.auth-enabled = cfg.auth.enable;
|
||||
|
||||
systemd.services.influxdb-account-manager = {
|
||||
description = "InfluxDB accounts and databases";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "influxdb.service" ] ++ keyservices;
|
||||
wants = keyservices;
|
||||
path = [ config.services.influxdb.package ];
|
||||
script =
|
||||
# Configure authentication:
|
||||
(optionalString cfg.auth.enable ''
|
||||
export INFLUX_USERNAME="${cfg.superuser.name}"
|
||||
export INFLUX_PASSWORD=$(head -n 1 "${cfg.superuser.passwordFile}")
|
||||
'') +
|
||||
# Create superuser:
|
||||
(optionalString cfg.auth.enable
|
||||
(createuser cfg.superuser.name cfg.superuser.passwordFile true)) +
|
||||
# Create all other users:
|
||||
(concatMapStringsSep "\n"
|
||||
(a: createuser a.name a.passwordFile a.isAdmin) (attrValues cfg.accounts)) +
|
||||
# Create databases and grants:
|
||||
(concatMapStringsSep "\n" createdb (attrValues cfg.databases));
|
||||
};
|
||||
};
|
||||
}
|
21
modules/services/databases/influxdb/scripts.nix
Normal file
21
modules/services/databases/influxdb/scripts.nix
Normal file
|
@ -0,0 +1,21 @@
|
|||
{ config, lib, pkgs, ...}:
|
||||
|
||||
pkgs.stdenvNoCC.mkDerivation {
|
||||
name = "influx-account-manager";
|
||||
phases = [ "installPhase" "fixupPhase" ];
|
||||
|
||||
installPhase = ''
|
||||
# Substitution variables:
|
||||
mkdir -p $out/bin
|
||||
install -m 0555 ${./createdb.sh} $out/bin/createdb.sh
|
||||
install -m 0555 ${./createuser.sh} $out/bin/createuser.sh
|
||||
install -m 0555 ${./creategrant.sh} $out/bin/creategrant.sh
|
||||
'';
|
||||
|
||||
meta = with lib; {
|
||||
description = "Automatically create InfluxDB databases and users as needed.";
|
||||
homepage = https://git.devalot.com/pjones/phoebe/;
|
||||
maintainers = with maintainers; [ pjones ];
|
||||
platforms = platforms.all;
|
||||
};
|
||||
}
|
Loading…
Add table
Reference in a new issue