tracksolid_timescale_grafan.../dwh/261003_dwh_roles.sql

67 lines
2.7 KiB
MySQL
Raw Permalink Normal View History

-- =============================================================
-- DWH ROLES AUDIT
-- Target Database: tracksolid_dwh
-- Purpose: Assert that the n8n DWH pipeline's role contract holds:
-- - dwh_owner exists (writes bronze + dwh_control)
-- - grafana_ro exists (reads bronze + silver + gold + dwh_control)
-- - grafana_ro has CONNECT on the database
-- - grafana_ro has USAGE on every schema it needs
-- Applies after: 260423_dwh_ddl_v1.sql, 261001_dwh_control.sql
-- Idempotent: pure assertion, no CREATE ROLE or GRANT statements.
--
-- Why this file exists: 260423 creates both roles and grants bronze/silver/gold;
-- 261001 grants dwh_control. This file is a single checkpoint that verifies
-- those prior migrations were applied in the right order, and fails loudly
-- if anything is missing before the pipeline goes live.
--
-- Password rotation and sslmode=require enforcement are out-of-band:
-- rotate via ALTER ROLE ... PASSWORD ... in a psql superuser session,
-- enforce SSL via the n8n credential (sslmode=require) — not SQL-level.
-- =============================================================
BEGIN;
DO $$
DECLARE
missing TEXT := '';
r RECORD;
BEGIN
-- 1. Roles exist
IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'dwh_owner') THEN
missing := missing || E'\n - role dwh_owner missing (expected from 260423)';
END IF;
IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'grafana_ro') THEN
missing := missing || E'\n - role grafana_ro missing (expected from 260423)';
END IF;
-- 2. grafana_ro CONNECT on this database
IF NOT has_database_privilege('grafana_ro', current_database(), 'CONNECT') THEN
missing := missing
|| format(E'\n - grafana_ro lacks CONNECT on database %s',
current_database());
END IF;
-- 3. grafana_ro USAGE on every schema the pipeline / dashboards touch
FOR r IN
SELECT unnest(ARRAY['bronze','silver','gold','dwh_control']) AS schema_name
LOOP
IF NOT EXISTS (SELECT 1 FROM pg_namespace WHERE nspname = r.schema_name) THEN
missing := missing
|| format(E'\n - schema %s missing (expected from 260423/261001)',
r.schema_name);
ELSIF NOT has_schema_privilege('grafana_ro', r.schema_name, 'USAGE') THEN
missing := missing
|| format(E'\n - grafana_ro lacks USAGE on schema %s',
r.schema_name);
END IF;
END LOOP;
IF length(missing) > 0 THEN
RAISE EXCEPTION E'DWH roles audit FAILED:%s', missing;
END IF;
RAISE NOTICE 'DWH roles audit OK: dwh_owner + grafana_ro present with expected grants.';
END$$;
COMMIT;