"""One-shot schema/role setup. Only this job receives database admin credentials.""" import os from pathlib import Path import psycopg from psycopg import sql def main(): role = os.environ['APP_DB_USER'] with psycopg.connect(os.environ['DATABASE_ADMIN_URL']) as c: admin, database = c.execute('SELECT current_user,current_database()').fetchone() if role == admin: raise RuntimeError('Application and database administrator must differ') if not c.execute('SELECT 1 FROM pg_roles WHERE rolname=%s', (role,)).fetchone(): c.execute(sql.SQL('CREATE ROLE {} LOGIN').format(sql.Identifier(role))) c.execute(sql.SQL('ALTER ROLE {} NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION NOBYPASSRLS PASSWORD {}').format( sql.Identifier(role), sql.Literal(os.environ['APP_DB_PASSWORD']))) c.execute(Path(__file__).with_name('schema.sql').read_text()) c.execute(sql.SQL('REVOKE CREATE ON SCHEMA public FROM PUBLIC')) c.execute(sql.SQL('GRANT CONNECT ON DATABASE {} TO {}').format(sql.Identifier(database),sql.Identifier(role))) c.execute(sql.SQL('GRANT USAGE ON SCHEMA dtf_local TO {}').format(sql.Identifier(role))) c.execute(sql.SQL('GRANT SELECT,INSERT,UPDATE,DELETE ON ALL TABLES IN SCHEMA dtf_local TO {}').format(sql.Identifier(role))) c.execute(sql.SQL('GRANT USAGE,SELECT ON ALL SEQUENCES IN SCHEMA dtf_local TO {}').format(sql.Identifier(role))) print('Local schema migrated; runtime role has DML only.') if __name__ == '__main__': main()