From 10dbf990f11d36eb68fb2616efe8104540294af9 Mon Sep 17 00:00:00 2001 From: Oleksii Kliukin Date: Thu, 30 Apr 2015 10:58:07 +0200 Subject: [PATCH] Allow md5 connections from outside and create connection roles. Create a superuser role with a given name and password (or change the postgres role if the name is not given). Also, create an admin role with the name and the password provided. The admin role has CREATEDB and CREATEROLE permisssions, effectively making it the most powerful role after the superuser. --- governor.py | 1 + helpers/postgresql.py | 15 ++++++++++++++- postgres0.yml | 5 +++++ postgres1.yml | 5 +++++ 4 files changed, 25 insertions(+), 1 deletion(-) diff --git a/governor.py b/governor.py index a6717faf..7492b0e5 100755 --- a/governor.py +++ b/governor.py @@ -53,6 +53,7 @@ if postgresql.data_directory_empty(): etcd.take_leader(postgresql.name) postgresql.start() postgresql.create_replication_user() + postgresql.create_connection_users() else: synced_from_leader = False while not synced_from_leader: diff --git a/helpers/postgresql.py b/helpers/postgresql.py index ecc81b02..3fdd1515 100644 --- a/helpers/postgresql.py +++ b/helpers/postgresql.py @@ -14,6 +14,8 @@ class Postgresql: self.host, self.port = config["listen"].split(":") self.data_dir = config["data_dir"] self.replication = config["replication"] + self.superuser = config.get('superuser') + self.admin_user = config.get('admin') self.config = config @@ -148,7 +150,9 @@ class Postgresql: f.write("host replication %(username)s %(network)s md5" % {"username": self.replication["username"], "network": self.replication["network"]}) # allow TCP connections from the host's own address - f.write("\nhost postgres postgres samehost trust\n" % {"network": self.host}) + f.write("\nhost postgres postgres samehost trust\n") + # allow TCP connections from the rest of the world with a password + f.write("\nhost postgres postgres 0.0.0.0/0 md5\n") f.close() def write_recovery_conf(self, leader_hash): @@ -183,5 +187,14 @@ recovery_target_timeline = 'latest' def create_replication_user(self): self.query("CREATE USER \"%s\" WITH REPLICATION ENCRYPTED PASSWORD '%s';" % (self.replication["username"], self.replication["password"])) + def create_connection_users(self): + if self.superuser: + if 'username' in self.superuser: + self.query("CREATE ROLE \"%s\" LOGIN SUPERUSER WITH PASSWORD '%s';".format(self.superuser["username"], self.superuser["password"])) + else: + self.query("ALTER ROLE postgres WITH PASSWORD '{0}'".format(self.superuser['password'])) + if self.admin: + self.query("CREATE ROLE \"%s\" LOGIN CREATEDB CREATEROLE WITH PASSWORD '%s';".format(self.admin["username"], self.admin["password"])) + def xlog_position(self): return self.query("SELECT pg_last_xlog_replay_location();").fetchone()[0] diff --git a/postgres0.yml b/postgres0.yml index 66d0b9eb..e7d05c5a 100644 --- a/postgres0.yml +++ b/postgres0.yml @@ -12,6 +12,11 @@ postgresql: username: replicator password: rep-pass network: 127.0.0.1/32 + superuser: + password: zalando + admin: + username: admin + password: admin #recovery_conf: #restore_command: cp ../wal_archive/%f %p parameters: diff --git a/postgres1.yml b/postgres1.yml index 1332291b..f18ebd17 100644 --- a/postgres1.yml +++ b/postgres1.yml @@ -12,6 +12,11 @@ postgresql: username: replicator password: rep-pass network: 127.0.0.1/32 + superuser: + password: zalando + admin: + username: admin + password: admin #recovery_conf: #restore_command: cp ../wal_archive/%f %p parameters: