Skip to content

Commit d42116b

Browse files
passcodreview-hero[bot]
andauthored
feat: grant REINDEX capability to analytics user in read-write mode (#15)
Co-authored-by: review-hero[bot] <2896273+review-hero[bot]@users.noreply.github.com>
1 parent e5e6563 commit d42116b

4 files changed

Lines changed: 39 additions & 22 deletions

File tree

.node-version

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
latest

src/controllers/replica.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1167,7 +1167,8 @@ async fn reconcile_schema_migration(
11671167
return Err(Error::SchemaMigration(msg));
11681168
}
11691169

1170-
// The analytics user already has pg_write_all_data + CREATE ON DATABASE
1170+
// The analytics user already has write privileges (superuser on PG < 17,
1171+
// pg_write_all_data + pg_maintain + CREATE ON DATABASE on PG >= 17)
11711172
// when persistent_schemas is configured (read_only is effectively false),
11721173
// so we reuse the replica creds secret for write access to the target.
11731174
let target_superuser_secret_name = reader_secret_name.clone();

src/controllers/restore/builders.rs

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -599,26 +599,31 @@ fi
599599
600600
echo "Detected PG major version: $PG_MAJOR"
601601
602-
if [ "$PG_MAJOR" -ge 14 ]; then
603-
psql -U postgres -d postgres << SQLEOF
602+
psql -U postgres -d postgres << SQLEOF
603+
\getenv analytics_password ANALYTICS_PASSWORD
604604
DO \$\$
605605
BEGIN
606606
IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = '${{ANALYTICS_USERNAME}}') THEN
607-
CREATE ROLE ${{ANALYTICS_USERNAME}} WITH LOGIN PASSWORD '${{ANALYTICS_PASSWORD}}';
608-
ELSE
609-
ALTER ROLE ${{ANALYTICS_USERNAME}} WITH PASSWORD '${{ANALYTICS_PASSWORD}}';
607+
CREATE ROLE ${{ANALYTICS_USERNAME}} WITH LOGIN;
610608
END IF;
611609
END
612610
\$\$;
611+
ALTER ROLE ${{ANALYTICS_USERNAME}} WITH PASSWORD :'analytics_password';
612+
SQLEOF
613+
614+
if [ "$PG_MAJOR" -ge 14 ] && [ "{read_only}" = "true" ]; then
615+
# PG >= 14 read-only: granular read role
616+
psql -U postgres -d postgres << SQLEOF
613617
GRANT pg_read_all_data TO ${{ANALYTICS_USERNAME}};
614618
SQLEOF
619+
echo "Read-only mode with PG >= 14, granted pg_read_all_data"
615620
616-
if [ "{read_only}" = "true" ]; then
617-
echo "Read-only mode with PG >= 14, granted pg_read_all_data"
618-
else
619-
echo "Read-write mode with PG >= 14, granting pg_write_all_data + CREATE ON DATABASE..."
620-
psql -U postgres -d postgres << SQLEOF
621+
elif [ "$PG_MAJOR" -ge 17 ] && [ "{read_only}" != "true" ]; then
622+
# PG >= 17 read-write: granular roles including pg_maintain
623+
psql -U postgres -d postgres << SQLEOF
624+
GRANT pg_read_all_data TO ${{ANALYTICS_USERNAME}};
621625
GRANT pg_write_all_data TO ${{ANALYTICS_USERNAME}};
626+
GRANT pg_maintain TO ${{ANALYTICS_USERNAME}};
622627
DO \$\$
623628
DECLARE
624629
dbname text;
@@ -630,19 +635,13 @@ BEGIN
630635
END
631636
\$\$;
632637
SQLEOF
633-
fi
638+
echo "Read-write mode with PG >= 17, granted pg_read_all_data + pg_write_all_data + pg_maintain + CREATE ON DATABASE"
639+
634640
else
635-
echo "PG < 14, granting superuser to analytics user..."
641+
# PG < 14, or PG 14-16 read-write: superuser
642+
echo "Granting superuser to analytics user (PG < 17 read-write or PG < 14)..."
636643
psql -U postgres -d postgres << SQLEOF
637-
DO \$\$
638-
BEGIN
639-
IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = '${{ANALYTICS_USERNAME}}') THEN
640-
CREATE ROLE ${{ANALYTICS_USERNAME}} WITH LOGIN SUPERUSER PASSWORD '${{ANALYTICS_PASSWORD}}';
641-
ELSE
642-
ALTER ROLE ${{ANALYTICS_USERNAME}} WITH SUPERUSER PASSWORD '${{ANALYTICS_PASSWORD}}';
643-
END IF;
644-
END
645-
\$\$;
644+
ALTER ROLE ${{ANALYTICS_USERNAME}} WITH SUPERUSER;
646645
SQLEOF
647646
fi
648647
echo "Writing restore metadata..."

tests/lifecycle.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,22 @@ async fn analytics_create_schema_read_write() {
399399
)
400400
.await;
401401

402+
println!("--- verifying analytics user can REINDEX");
403+
kubectl_exec(
404+
ns,
405+
&deploy_target,
406+
&[
407+
"psql",
408+
"-U",
409+
"analytics",
410+
"-d",
411+
"myapp",
412+
"-c",
413+
"REINDEX TABLE test_pgro_app.rw_test",
414+
],
415+
)
416+
.await;
417+
402418
println!("--- all read-write assertions passed, cleaning up");
403419
cleanup_namespace(&client, ns, &["rw-replica"]).await;
404420
}

0 commit comments

Comments
 (0)