def migrate_user(old_username, new_username, password, superuser=False): if postgresql.is_primary(): # We do this on any primary, as the master is # appointed later. It also works if we have # a weird setup with manual_replication and # multiple primaries. con = postgresql.connect() postgresql.ensure_user(con, new_username, password, superuser=superuser) cur = con.cursor() hookenv.log("Granting old role {} to new role {}" "".format(old_username, new_username)) cur.execute( "GRANT %s TO %s", ( postgresql.pgidentifier(old_username), postgresql.pgidentifier(new_username), ), ) con.commit() else: hookenv.log("Primary must map role {!r} to {!r}" "".format(old_username, new_username))
def create_replication_user(): username = replication_username() hookenv.log("Creating replication user {}".format(username)) con = postgresql.connect() postgresql.ensure_user(con, username, leader_get("replication_password"), replication=True) con.commit() reactive.set_state("postgresql.replication.replication_user_created")
def ensure_db_relation_resources(rel): """Create the database resources needed for the relation.""" master = rel.local if "password" not in master: return hookenv.log("Ensuring database {!r} and user {!r} exist for {}" "".format(master["database"], master["user"], rel)) # First create the database, if it isn't already. postgresql.ensure_database(master["database"]) # Next, connect to the database to create the rest in a transaction. con = postgresql.connect(database=master["database"]) superuser, replication = _credential_types(rel) postgresql.ensure_user( con, master["user"], master["password"], superuser=superuser, replication=replication, ) if not superuser: postgresql.ensure_user(con, master["schema_user"], master["schema_password"]) # Grant specified privileges on the database to the user. This comes # from the PostgreSQL service configuration, as allowing the # relation to specify how much access it gets is insecure. config = hookenv.config() privs = set(filter(None, config["relation_database_privileges"].split(","))) postgresql.grant_database_privileges(con, master["user"], master["database"], privs) if not superuser: postgresql.grant_database_privileges(con, master["schema_user"], master["database"], privs) # Reset the roles granted to the user as requested. if "roles" in master: roles = filter(None, master.get("roles", "").split(",")) postgresql.grant_user_roles(con, master["user"], roles) # Create requested extensions. We never drop extensions, as there # may be dependent objects. if "extensions" in master: extensions = list(filter(None, master.get("extensions", "").split(","))) # Convert to the (extension, schema) tuple expected by # postgresql.ensure_extensions for i in range(0, len(extensions)): m = re.search(r"^\s*([^(\s]+)\s*(?:\((\w+)\))?", extensions[i]) if m is None: raise RuntimeError("Invalid extension {}".format(extensions[i])) extensions[i] = (m.group(1), m.group(2) or "public") postgresql.ensure_extensions(con, extensions) con.commit() # Don't throw away our changes.
def migrate_user(old_username, new_username, password, superuser=False): if postgresql.is_primary(): # We do this on any primary, as the master is # appointed later. It also works if we have # a weird setup with manual_replication and # multiple primaries. con = postgresql.connect() postgresql.ensure_user(con, new_username, password, superuser=superuser) cur = con.cursor() hookenv.log('Granting old role {} to new role {}' ''.format(old_username, new_username)) cur.execute('GRANT %s TO %s', (postgresql.pgidentifier(old_username), postgresql.pgidentifier(new_username))) con.commit() else: hookenv.log('Primary must map role {!r} to {!r}' ''.format(old_username, new_username))
def test_ensure_user(self, role_exists, pgidentifier): con = MagicMock() cur = con.cursor() # Create a new boring user role_exists.return_value = False pgidentifier.return_value = sentinel.quoted_user postgresql.ensure_user(con, sentinel.user, sentinel.secret) pgidentifier.assert_called_once_with(sentinel.user) cur.execute.assert_called_once_with( "CREATE ROLE %s WITH LOGIN NOSUPERUSER NOREPLICATION PASSWORD %s", (sentinel.quoted_user, sentinel.secret) ) # Ensure an existing user is a superuser role_exists.return_value = True cur.execute.reset_mock() postgresql.ensure_user(con, sentinel.user, sentinel.secret, superuser=True) cur.execute.assert_called_once_with( "ALTER ROLE %s WITH LOGIN SUPERUSER NOREPLICATION PASSWORD %s", (sentinel.quoted_user, sentinel.secret) ) # Create a new user with replication permissions. role_exists.return_value = False cur.execute.reset_mock() postgresql.ensure_user(con, sentinel.user, sentinel.secret, replication=True) cur.execute.assert_called_once_with( "CREATE ROLE %s WITH LOGIN NOSUPERUSER REPLICATION PASSWORD %s", (sentinel.quoted_user, sentinel.secret) )
def test_ensure_user(self, role_exists, pgidentifier): con = MagicMock() cur = con.cursor() # Create a new boring user role_exists.return_value = False pgidentifier.return_value = sentinel.quoted_user postgresql.ensure_user(con, sentinel.user, sentinel.secret) pgidentifier.assert_called_once_with(sentinel.user) cur.execute.assert_called_once_with( 'CREATE ROLE %s WITH LOGIN NOSUPERUSER NOREPLICATION PASSWORD %s', (sentinel.quoted_user, sentinel.secret)) # Ensure an existing user is a superuser role_exists.return_value = True cur.execute.reset_mock() postgresql.ensure_user(con, sentinel.user, sentinel.secret, superuser=True) cur.execute.assert_called_once_with( 'ALTER ROLE %s WITH LOGIN SUPERUSER NOREPLICATION PASSWORD %s', (sentinel.quoted_user, sentinel.secret)) # Create a new user with replication permissions. role_exists.return_value = False cur.execute.reset_mock() postgresql.ensure_user(con, sentinel.user, sentinel.secret, replication=True) cur.execute.assert_called_once_with( 'CREATE ROLE %s WITH LOGIN NOSUPERUSER REPLICATION PASSWORD %s', (sentinel.quoted_user, sentinel.secret))
def ensure_db_relation_resources(rel): """Create the database resources needed for the relation.""" master = rel.local hookenv.log("Ensuring database {!r} and user {!r} exist for {}" "".format(master["database"], master["user"], rel)) # First create the database, if it isn't already. postgresql.ensure_database(master["database"]) # Next, connect to the database to create the rest in a transaction. con = postgresql.connect(database=master["database"]) superuser, replication = _credential_types(rel) postgresql.ensure_user(con, master["user"], master["password"], superuser=superuser, replication=replication) if not superuser: postgresql.ensure_user(con, master["schema_user"], master["schema_password"]) # Grant specified privileges on the database to the user. This comes # from the PostgreSQL service configuration, as allowing the # relation to specify how much access it gets is insecure. config = hookenv.config() privs = set(filter(None, config["relation_database_privileges"].split(","))) postgresql.grant_database_privileges(con, master["user"], master["database"], privs) if not superuser: postgresql.grant_database_privileges(con, master["schema_user"], master["database"], privs) # Reset the roles granted to the user as requested. if "roles" in master: roles = filter(None, master.get("roles", "").split(",")) postgresql.grant_user_roles(con, master["user"], roles) # Create requested extensions. We never drop extensions, as there # may be dependent objects. if "extensions" in master: extensions = filter(None, master.get("extensions", "").split(",")) postgresql.ensure_extensions(con, extensions) con.commit() # Don't throw away our changes.
def ensure_nagios_user(): con = postgresql.connect() postgresql.ensure_user(con, nagios_username(), leadership.leader_get("nagios_password")) con.commit() reactive.set_state("postgresql.nagios.user_ensured")