Merge commit 'dd7fff655' into problame/standby-horizon-leases

This commit is contained in:
Christian Schwarz
2025-08-06 17:54:17 +02:00
51 changed files with 499 additions and 134 deletions

View File

@@ -503,6 +503,7 @@ class NeonLocalCli(AbstractNeonCli):
pageserver_id: int | None = None,
allow_multiple=False,
update_catalog: bool = False,
privileged_role_name: str | None = None,
features: list[str] | None = None,
) -> subprocess.CompletedProcess[str]:
args = [
@@ -535,6 +536,8 @@ class NeonLocalCli(AbstractNeonCli):
args.extend(["--allow-multiple"])
if update_catalog:
args.extend(["--update-catalog"])
if privileged_role_name is not None:
args.extend(["--privileged-role-name", privileged_role_name])
if features is not None:
args.extend(["--features", json.dumps(features)])

View File

@@ -4326,6 +4326,7 @@ class Endpoint(PgProtocol, LogUtils):
pageserver_id: int | None = None,
allow_multiple: bool = False,
update_catalog: bool = False,
privileged_role_name: str | None = None,
features: list[str] | None = None,
) -> Self:
"""
@@ -4354,6 +4355,7 @@ class Endpoint(PgProtocol, LogUtils):
pageserver_id=pageserver_id,
allow_multiple=allow_multiple,
update_catalog=update_catalog,
privileged_role_name=privileged_role_name,
features=features,
)
path = Path("endpoints") / self.endpoint_id / "pgdata"
@@ -4808,6 +4810,7 @@ class EndpointFactory:
config_lines: list[str] | None = None,
pageserver_id: int | None = None,
update_catalog: bool = False,
privileged_role_name: str | None = None,
features: list[str] | None = None,
) -> Endpoint:
ep = Endpoint(
@@ -4832,6 +4835,7 @@ class EndpointFactory:
config_lines=config_lines,
pageserver_id=pageserver_id,
update_catalog=update_catalog,
privileged_role_name=privileged_role_name,
features=features,
)

View File

@@ -103,3 +103,90 @@ def test_neon_superuser(neon_simple_env: NeonEnv, pg_version: PgVersion):
query = "DROP SUBSCRIPTION sub CASCADE"
log.info(f"Dropping subscription: {query}")
cur.execute(query)
def test_privileged_role_override(neon_simple_env: NeonEnv, pg_version: PgVersion):
"""
Test that we can override the privileged role for an endpoint and when we do it,
everything is correctly bootstrapped inside Postgres and we don't have neon_superuser
role in the database.
"""
PRIVILEGED_ROLE_NAME = "my_superuser"
env = neon_simple_env
env.create_branch("test_privileged_role_override")
ep = env.endpoints.create(
"test_privileged_role_override",
privileged_role_name=PRIVILEGED_ROLE_NAME,
update_catalog=True,
)
ep.start()
ep.wait_for_migrations()
member_roles = [
"pg_read_all_data",
"pg_write_all_data",
"pg_monitor",
"pg_signal_backend",
]
non_member_roles = [
"pg_execute_server_program",
"pg_read_server_files",
"pg_write_server_files",
]
role_attributes = {
"rolsuper": False,
"rolinherit": True,
"rolcreaterole": True,
"rolcreatedb": True,
"rolcanlogin": False,
"rolreplication": True,
"rolconnlimit": -1,
"rolbypassrls": True,
}
if pg_version >= PgVersion.V15:
non_member_roles.append("pg_checkpoint")
if pg_version >= PgVersion.V16:
member_roles.append("pg_create_subscription")
non_member_roles.append("pg_use_reserved_connections")
with ep.cursor() as cur:
cur.execute(f"SELECT rolname FROM pg_roles WHERE rolname = '{PRIVILEGED_ROLE_NAME}'")
assert cur.fetchall()[0][0] == PRIVILEGED_ROLE_NAME
cur.execute("SELECT rolname FROM pg_roles WHERE rolname = 'neon_superuser'")
assert len(cur.fetchall()) == 0
cur.execute("SHOW neon.privileged_role_name")
assert cur.fetchall()[0][0] == PRIVILEGED_ROLE_NAME
# check PRIVILEGED_ROLE_NAME role is created
cur.execute(f"select * from pg_roles where rolname = '{PRIVILEGED_ROLE_NAME}'")
assert cur.fetchone() is not None
# check PRIVILEGED_ROLE_NAME role has the correct member roles
for role in member_roles:
cur.execute(f"SELECT pg_has_role('{PRIVILEGED_ROLE_NAME}', '{role}', 'member')")
assert cur.fetchone() == (True,), (
f"Role {role} should be a member of {PRIVILEGED_ROLE_NAME}"
)
for role in non_member_roles:
cur.execute(f"SELECT pg_has_role('{PRIVILEGED_ROLE_NAME}', '{role}', 'member')")
assert cur.fetchone() == (False,), (
f"Role {role} should not be a member of {PRIVILEGED_ROLE_NAME}"
)
# check PRIVILEGED_ROLE_NAME role has the correct role attributes
for attr, val in role_attributes.items():
cur.execute(f"SELECT {attr} FROM pg_roles WHERE rolname = '{PRIVILEGED_ROLE_NAME}'")
curr_val = cur.fetchone()
assert curr_val == (val,), (
f"Role attribute {attr} should be {val} instead of {curr_val}"
)