update publik-create-databases
This commit is contained in:
parent
d9bd5ee59d
commit
0dd73b2641
|
@ -2,6 +2,5 @@ publik-create-users /usr/bin
|
|||
publik-create-databases /usr/bin
|
||||
publik-cluster-link /usr/bin
|
||||
publik-emailconf /usr/bin
|
||||
publik.conf.example /etc/publik
|
||||
nginx/conf.d/* etc/nginx/conf.d
|
||||
nginx/snippets/*.conf etc/nginx/snippets
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
#! /bin/sh
|
||||
set -e
|
||||
|
||||
case "$1" in
|
||||
configure)
|
||||
chmod 600 /etc/publik/publik.conf.example
|
||||
;;
|
||||
|
||||
triggered)
|
||||
;;
|
||||
|
||||
abort-upgrade|abort-remove|abort-deconfigure)
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "postinst called with unknown argument \`$1'" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
#DEBHELPER#
|
||||
|
||||
exit 0
|
|
@ -1,130 +1,77 @@
|
|||
#!/usr/bin/python3
|
||||
import os
|
||||
import argparse
|
||||
import os
|
||||
import random
|
||||
import string
|
||||
import subprocess
|
||||
import yaml
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--config', type=str, default='/etc/publik/publik.conf')
|
||||
parser.add_argument('--simulate', action='store_true')
|
||||
parser.add_argument('--configure', action='store_true')
|
||||
args = parser.parse_args()
|
||||
|
||||
model = """DATABASES['default']['HOST'] = '{host}'
|
||||
DATABASES['default']['PORT'] = {port}
|
||||
DATABASES['default']['PASSWORD'] = '{password}'"""
|
||||
import sys
|
||||
|
||||
|
||||
def run_pg(connection, cmd):
|
||||
cmd = cmd.replace('"', '\\"')
|
||||
if connection.get('host') == 'localhost' and not connection.get('admin'):
|
||||
subprocess.call('echo "%s" | sudo -u postgres psql' % cmd, shell=True)
|
||||
publik = {
|
||||
"authentic2-multitenant": {
|
||||
"database": "authentic2_multitenant",
|
||||
"user": "authentic-multitenant",
|
||||
"extensions": ["unaccent", "pg_trgm"],
|
||||
},
|
||||
"bijoe": {},
|
||||
"chrono": {},
|
||||
"combo": {"extensions": ["unaccent"]},
|
||||
"fargo": {},
|
||||
"hobo": {},
|
||||
"passerelle": {},
|
||||
"wcs": {},
|
||||
"welco": {},
|
||||
}
|
||||
|
||||
|
||||
def run(command, database="postgres", fake=False):
|
||||
cmd = 'sudo -u postgres psql -c "%s" %s' % (command.replace('"', '\\"'), database)
|
||||
if fake:
|
||||
print(cmd)
|
||||
else:
|
||||
admin = connection.get('admin')
|
||||
subprocess.call("echo '%s' | psql -h -U %s -W" % (cmd, admin), shell=True)
|
||||
subprocess.run(cmd, shell=True, check=True)
|
||||
|
||||
|
||||
def main():
|
||||
if not os.path.isfile(args.config):
|
||||
raise(Exception('Configuration file not found: %s' % args.config))
|
||||
|
||||
with open(args.config) as fh:
|
||||
cfg = yaml.load(fh)
|
||||
|
||||
if 'defaults' in cfg.keys():
|
||||
defaults = cfg.get('defaults')
|
||||
else:
|
||||
defaults = {}
|
||||
|
||||
if 'databases' not in defaults.keys() and 'instances' not in cfg.keys():
|
||||
raise(Exception('No "instances" nor "defaults" keys found in configuration file'))
|
||||
|
||||
for instance, data in cfg['instances'].items():
|
||||
if 'databases' not in data.keys():
|
||||
data['databases'] = defaults['databases']
|
||||
|
||||
if 'connection' in defaults.keys():
|
||||
connection = defaults['connection']
|
||||
if 'connection' in data.keys():
|
||||
connection.update(data['connection'])
|
||||
else:
|
||||
connection = data['connection']
|
||||
def write_setting(brique, host, port, password):
|
||||
settings_d = "/etc/%s/settings.d" % brique
|
||||
settings = "%s/database.py" % settings_d
|
||||
if not os.path.isdir(settings_d):
|
||||
os.system('mkdir -p %s' % settings_d)
|
||||
with open(settings, "w") as fh:
|
||||
fh.write("DATABASES['default']['HOST'] = '{host}'\n"
|
||||
"DATABASES['default']['PORT'] = {port}\n"
|
||||
"DATABASES['default']['PASSWORD'] = '{password}'".format(host=host, port=port, password=password))
|
||||
|
||||
|
||||
if args.configure:
|
||||
if 'roles' not in data.keys():
|
||||
raise(Exception('Not implemented: no passwords defined'))
|
||||
configure_briques(connection, data['databases'], data['roles'])
|
||||
else:
|
||||
if 'roles' not in data.keys():
|
||||
print('No "roles" key found, going for passwordless configuration')
|
||||
data['roles'] = False
|
||||
create_databases(connection, instance, data['databases'], data['roles'])
|
||||
def main(args):
|
||||
for brique, data in publik.items():
|
||||
database = data.get("database", brique)
|
||||
user = data.get("user", brique)
|
||||
extensions = data.get("extensions")
|
||||
run('CREATE USER "%s";' % user, fake=args.fake)
|
||||
if user == "wcs":
|
||||
run("ALTER USER wcs CREATEDB;", fake=args.fake)
|
||||
if args.password:
|
||||
password = "".join(random.choice(string.ascii_letters + string.digits) for _ in range(16))
|
||||
run("ALTER USER \"%s\" with password '%s';" % (user, password), fake=args.fake)
|
||||
run("CREATE DATABASE {} WITH OWNER = \"{}\" TEMPLATE = template0 "
|
||||
"LC_COLLATE = 'fr_FR.UTF-8' LC_CTYPE = 'fr_FR.UTF-8';".format(database, user), fake=args.fake)
|
||||
if extensions:
|
||||
for e in extensions:
|
||||
run("CREATE EXTENSION %s;" % e, database=database, fake=args.fake)
|
||||
if not args.fake and args.password:
|
||||
write_setting(brique, args.host, args.port, password)
|
||||
|
||||
|
||||
def configure_briques(connection, databases, roles):
|
||||
for database, role in databases.items():
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--password", action="store_true", help="generate password")
|
||||
parser.add_argument("--fake", action="store_true", help="dry-run")
|
||||
parser.add_argument("--host", default="localhost")
|
||||
parser.add_argument("--port", default="5432")
|
||||
args = parser.parse_args()
|
||||
|
||||
if database == 'wcs':
|
||||
continue
|
||||
if not args.fake and os.geteuid() != 0:
|
||||
sys.exit("You need to have privileges to run this script, please try again with sudo.")
|
||||
|
||||
password = roles[role]
|
||||
if database == 'authentic2_multitenant':
|
||||
service = 'authentic2-multitenant'
|
||||
user = 'authentic-multitenant'
|
||||
else:
|
||||
user, service = database, database
|
||||
settings_d = '/etc/%s/settings.d' % service
|
||||
settings = '%s/connection.py' % settings_d
|
||||
|
||||
if not os.path.isdir(settings_d) and not args.simultate:
|
||||
os.system('mkdir -p %s' % settings_d)
|
||||
|
||||
s = model.format(database=database, host=connection['host'],
|
||||
port=connection['port'], password=password)
|
||||
|
||||
if args.simulate:
|
||||
print(s)
|
||||
continue
|
||||
|
||||
with open(settings, 'w') as fh:
|
||||
fh.write(s)
|
||||
|
||||
os.system('chown -R %s %s' % (user, settings_d))
|
||||
|
||||
|
||||
def create_databases(connection, instance, databases, roles):
|
||||
count = len(databases.keys())
|
||||
print('instance {} has {} components'.format(instance, count))
|
||||
|
||||
cmds = []
|
||||
for database, role in databases.items():
|
||||
if roles:
|
||||
password = roles[role]
|
||||
else:
|
||||
password = False
|
||||
cmds.append(gen_cmd(database, role, password))
|
||||
|
||||
if args.simulate:
|
||||
print(connection)
|
||||
for c in cmds:
|
||||
print(c)
|
||||
else:
|
||||
run_pg(connection, " ".join(cmds))
|
||||
|
||||
|
||||
def gen_cmd(database, role, password):
|
||||
out = []
|
||||
if password:
|
||||
out.append("CREATE USER \"{}\" PASSWORD '{}';".format(role, password))
|
||||
else:
|
||||
out.append("CREATE USER \"{}\";".format(role))
|
||||
out.append("CREATE DATABASE {} WITH OWNER = \"{}\" TEMPLATE = template0 "
|
||||
"LC_COLLATE = 'fr_FR.UTF-8' LC_CTYPE = 'fr_FR.UTF-8';".format(database, role))
|
||||
if database == 'wcs':
|
||||
out.append("ALTER USER wcs CREATEDB;")
|
||||
return " ".join(out)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
main(args)
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
defaults:
|
||||
connection:
|
||||
# the following is suitable for a local postgresql service
|
||||
host: localhost
|
||||
admin:
|
||||
password:
|
||||
databases:
|
||||
authentic2_multitenant: authentic-multitenant
|
||||
bijoe: bijoe
|
||||
chrono: chrono
|
||||
combo: combo
|
||||
fargo: fargo
|
||||
hobo: hobo
|
||||
passerelle: passerelle
|
||||
wcs: wcs
|
||||
welco: welco
|
||||
briques:
|
||||
- authentic2-multitenant
|
||||
- bijoe
|
||||
- chrono
|
||||
- combo
|
||||
- hobo
|
||||
- fargo
|
||||
- passerelle
|
||||
- welco
|
||||
- wcs
|
||||
|
||||
instances:
|
||||
local.publik: {}
|
||||
|
||||
## Example
|
||||
# instances:
|
||||
# demo.local.publik:
|
||||
# connection:
|
||||
# host: w.x.y.z
|
||||
# admin: admin
|
||||
# password: secret
|
||||
# databases:
|
||||
# authentic2_multitenant: authentic-multitenant
|
||||
# combo: combo
|
||||
# roles:
|
||||
# authentic-multitenant: juzi3Uhi
|
||||
# combo: j0kl32fa
|
Loading…
Reference in New Issue