131 lines
4.1 KiB
Python
Executable File
131 lines
4.1 KiB
Python
Executable File
#!/usr/bin/python3
|
|
import os
|
|
import argparse
|
|
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}'"""
|
|
|
|
|
|
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)
|
|
else:
|
|
admin = connection.get('admin')
|
|
subprocess.call("echo '%s' | psql -h -U %s -W" % (cmd, admin), shell=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']
|
|
|
|
|
|
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 configure_briques(connection, databases, roles):
|
|
for database, role in databases.items():
|
|
|
|
if database == 'wcs':
|
|
continue
|
|
|
|
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()
|