Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .node-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
latest
3 changes: 2 additions & 1 deletion src/controllers/replica.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1167,7 +1167,8 @@ async fn reconcile_schema_migration(
return Err(Error::SchemaMigration(msg));
}

// The analytics user already has pg_write_all_data + CREATE ON DATABASE
// The analytics user already has write privileges (superuser on PG < 17,
// pg_write_all_data + pg_maintain + CREATE ON DATABASE on PG >= 17)
// when persistent_schemas is configured (read_only is effectively false),
// so we reuse the replica creds secret for write access to the target.
let target_superuser_secret_name = reader_secret_name.clone();
Expand Down
41 changes: 20 additions & 21 deletions src/controllers/restore/builders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -599,26 +599,31 @@ fi

echo "Detected PG major version: $PG_MAJOR"

if [ "$PG_MAJOR" -ge 14 ]; then
psql -U postgres -d postgres << SQLEOF
psql -U postgres -d postgres << SQLEOF
\getenv analytics_password ANALYTICS_PASSWORD
DO \$\$
BEGIN
IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = '${{ANALYTICS_USERNAME}}') THEN
CREATE ROLE ${{ANALYTICS_USERNAME}} WITH LOGIN PASSWORD '${{ANALYTICS_PASSWORD}}';
ELSE
ALTER ROLE ${{ANALYTICS_USERNAME}} WITH PASSWORD '${{ANALYTICS_PASSWORD}}';
CREATE ROLE ${{ANALYTICS_USERNAME}} WITH LOGIN;
END IF;
END
\$\$;
ALTER ROLE ${{ANALYTICS_USERNAME}} WITH PASSWORD :'analytics_password';
SQLEOF

if [ "$PG_MAJOR" -ge 14 ] && [ "{read_only}" = "true" ]; then
# PG >= 14 read-only: granular read role
psql -U postgres -d postgres << SQLEOF
GRANT pg_read_all_data TO ${{ANALYTICS_USERNAME}};
SQLEOF
echo "Read-only mode with PG >= 14, granted pg_read_all_data"

Comment thread
review-hero[bot] marked this conversation as resolved.
if [ "{read_only}" = "true" ]; then
echo "Read-only mode with PG >= 14, granted pg_read_all_data"
else
echo "Read-write mode with PG >= 14, granting pg_write_all_data + CREATE ON DATABASE..."
psql -U postgres -d postgres << SQLEOF
elif [ "$PG_MAJOR" -ge 17 ] && [ "{read_only}" != "true" ]; then
# PG >= 17 read-write: granular roles including pg_maintain
psql -U postgres -d postgres << SQLEOF
GRANT pg_read_all_data TO ${{ANALYTICS_USERNAME}};
GRANT pg_write_all_data TO ${{ANALYTICS_USERNAME}};
GRANT pg_maintain TO ${{ANALYTICS_USERNAME}};
DO \$\$
DECLARE
dbname text;
Expand All @@ -630,19 +635,13 @@ BEGIN
END
\$\$;
SQLEOF
fi
echo "Read-write mode with PG >= 17, granted pg_read_all_data + pg_write_all_data + pg_maintain + CREATE ON DATABASE"

else
echo "PG < 14, granting superuser to analytics user..."
# PG < 14, or PG 14-16 read-write: superuser
echo "Granting superuser to analytics user (PG < 17 read-write or PG < 14)..."
psql -U postgres -d postgres << SQLEOF
DO \$\$
BEGIN
IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = '${{ANALYTICS_USERNAME}}') THEN
CREATE ROLE ${{ANALYTICS_USERNAME}} WITH LOGIN SUPERUSER PASSWORD '${{ANALYTICS_PASSWORD}}';
ELSE
ALTER ROLE ${{ANALYTICS_USERNAME}} WITH SUPERUSER PASSWORD '${{ANALYTICS_PASSWORD}}';
END IF;
END
\$\$;
ALTER ROLE ${{ANALYTICS_USERNAME}} WITH SUPERUSER;
SQLEOF
fi
echo "Writing restore metadata..."
Expand Down
16 changes: 16 additions & 0 deletions tests/lifecycle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,22 @@ async fn analytics_create_schema_read_write() {
)
.await;

println!("--- verifying analytics user can REINDEX");
kubectl_exec(
ns,
&deploy_target,
&[
"psql",
"-U",
"analytics",
"-d",
"myapp",
"-c",
"REINDEX TABLE test_pgro_app.rw_test",
],
)
.await;

println!("--- all read-write assertions passed, cleaning up");
cleanup_namespace(&client, ns, &["rw-replica"]).await;
}
Expand Down