Skip to content

Commit 8167a63

Browse files
committed
comments, rework pg_hba func
1 parent 4c534cf commit 8167a63

File tree

1 file changed

+59
-50
lines changed

1 file changed

+59
-50
lines changed

internal/controller/postgrescluster/metrics_setup.sql

Lines changed: 59 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -221,33 +221,49 @@ END;
221221
$$ LANGUAGE plpgsql;
222222

223223
/*
224-
-- TODO: WHAT IS REALLY HAPPENING HERE?
225-
* Tables and functions for monitoring changes to pg_hba_file_rules system catalogs.
226-
* Tables allow recording of existing settings so they can be referred back to to see what changed
227-
* If checksum function returns 0, then NO settings have changed
228-
* If checksum function returns 1, then something has changed since last known valid state
229-
* For replicas, logging past settings is not possible to compare what may have changed
230-
* For replicas, by default, it is expected that its settings will match the primary
231-
* For replicas, if the pg_hba.conf are necessarily different from the primary, a known good hash of that replica's
232-
settings can be sent as an argument to the relevant checksum function. Views are provided to easily obtain the hash values used by this monitoring tool.
233-
* If any known hash parameters are passed to the checksum function, note that it will override any past hash values stored in the log table when doing comparisons and completely re-evaluate the entire state. This is true even if done on a primary where the current state will then also be logged for comparison if it differs from the given hash.
234-
Taken from https://github.com/CrunchyData/pgmonitor/blob/development/postgres_exporter/common
235-
*/
224+
* The `pg_hba_checksum` table, functions, and view are taken from
225+
* https://github.com/CrunchyData/pgmonitor/blob/development/postgres_exporter/common
226+
*
227+
* The goal of these table, functions, and view is to monitor changes
228+
* to the pg_hba_file_rules system catalog.
229+
*
230+
* This material is used in the metric `ccp_pg_hba_checksum`.
231+
*/
236232

237-
-- Table used to store the old pg_hba, hash, and set the valid column
233+
/*
234+
* `monitor.pg_hba_checksum` table is used to store
235+
* - the pg_hba settings as string (for reference)
236+
* - the pg_hba settings as hash (for quick comparison)
237+
* - the `hba_hash_known_provided` (for overide hash manually given to the `monitor.pg_hba_checksum` function)
238+
* - the `valid` field to signal whether the pg_hba settings have not changed since they were accepted as valid
239+
*
240+
* We create an index on `created_at` in order to pull the most recent entry for
241+
* comparison in the `monitor.pg_hba_checksum` function
242+
*/
238243
DROP TABLE IF EXISTS monitor.pg_hba_checksum;
239244
CREATE TABLE monitor.pg_hba_checksum (
240245
hba_hash_generated text NOT NULL
241246
, hba_hash_known_provided text
242247
, hba_string text NOT NULL
243248
, created_at timestamptz DEFAULT now() NOT NULL
244249
, valid smallint NOT NULL );
245-
246250
COMMENT ON COLUMN monitor.pg_hba_checksum.valid IS 'Set this column to zero if this group of settings is a valid change';
247251
CREATE INDEX ON monitor.pg_hba_checksum (created_at);
248-
-- End table that stores pg_hba hash
249252

250-
-- Function used to compare old pg_hba hash and current hash
253+
/*
254+
* `monitor.pg_hba_checksum(text)` is used to compare the previous pg_hba hash
255+
* with a hash made of the current pg_hba hash, derived from the `monitor.pg_hba_hash` view below.
256+
*
257+
* This function returns
258+
* - 0, indicating NO settings have changed
259+
* - 1, indicating something has changed since last known valid state
260+
*
261+
* `monitor.pg_hba_checksum` can take a hash to be used as an override.
262+
* This may be useful when you have a standby with different pg_hba rules;
263+
* since it will have different rules (and therefore a different hash), you
264+
* could alter the metric function to pass the actual hash, which would be
265+
* used in lieu of this table's value (derived from the primary cluster's rules).
266+
*/
251267
DROP FUNCTION IF EXISTS monitor.pg_hba_checksum(text);
252268
CREATE FUNCTION monitor.pg_hba_checksum(p_known_hba_hash text DEFAULT NULL)
253269
RETURNS smallint
@@ -264,73 +280,67 @@ v_valid smallint;
264280

265281
BEGIN
266282

267-
SELECT pg_is_in_recovery() INTO v_is_in_recovery;
268-
283+
-- Retrieve the current settings from the `monitor.pg_hba_hash` view below
269284
IF current_setting('server_version_num')::int >= 100000 THEN
270-
271285
SELECT sha256_hash, hba_string
272286
INTO v_hba_hash, v_hba_string
273287
FROM monitor.pg_hba_hash;
274-
275288
ELSE
276289
RAISE EXCEPTION 'pg_hba change monitoring unsupported in versions older than PostgreSQL 10';
277290
END IF;
278291

292+
-- Retrieve the last previous hash from the table
279293
SELECT hba_hash_generated, valid
280294
INTO v_hba_hash_old, v_valid
281295
FROM monitor.pg_hba_checksum
282296
ORDER BY created_at DESC LIMIT 1;
283297

298+
-- If an manual/override hash has been given, we will use that:
299+
-- Do not base validity on the stored value if manual hash is given.
284300
IF p_known_hba_hash IS NOT NULL THEN
285301
v_hba_hash_old := p_known_hba_hash;
286-
-- Do not base validity on the stored value if manual hash is given.
287302
v_valid := 0;
288303
END IF;
289304

290-
IF (v_hba_hash_old IS NOT NULL) THEN
291-
292-
IF (v_hba_hash != v_hba_hash_old) THEN
293-
294-
v_valid := 1;
295-
296-
IF v_is_in_recovery = false THEN
297-
INSERT INTO monitor.pg_hba_checksum (
298-
hba_hash_generated
299-
, hba_hash_known_provided
300-
, hba_string
301-
, valid)
302-
VALUES (
303-
v_hba_hash
304-
, p_known_hba_hash
305-
, v_hba_string
306-
, v_valid);
307-
END IF;
308-
END IF;
309-
305+
IF (v_hba_hash_old IS NOT NULL) AND (v_hba_hash != v_hba_hash_old) THEN
306+
v_valid := 1;
310307
ELSE
311-
312308
v_valid := 0;
309+
END IF;
310+
311+
/*
312+
* We only want to insert into the table if we're on a primary and
313+
* - the table/manually entered hash is empty, e.g., we've just started the cluster; or
314+
* - the hashes don't match
315+
*
316+
* There's no value added by inserting into the table when no change was detected.
317+
*/
318+
IF (v_hba_hash_old IS NULL) OR (v_hba_hash != v_hba_hash_old) THEN
319+
SELECT pg_is_in_recovery() INTO v_is_in_recovery;
313320
IF v_is_in_recovery = false THEN
314321
INSERT INTO monitor.pg_hba_checksum (
315322
hba_hash_generated
316323
, hba_hash_known_provided
317324
, hba_string
318325
, valid)
319-
VALUES (v_hba_hash
326+
VALUES (
327+
v_hba_hash
320328
, p_known_hba_hash
321329
, v_hba_string
322330
, v_valid);
323331
END IF;
324-
325332
END IF;
326333

327334
RETURN v_valid;
328335

329336
END
330337
$function$;
331-
-- End function used to compare hashes
332338

333-
-- View used to create hash of pg_hba
339+
/*
340+
* The `monitor.pg_hba_hash` view return both a hash and a string aggregate of the
341+
* pg_catalog.pg_hba_file_rules.
342+
* Note: We use `sha256` to hash to allow this to run on FIPS environments.
343+
*/
334344
DROP VIEW IF EXISTS monitor.pg_hba_hash;
335345
CREATE VIEW monitor.pg_hba_hash AS
336346
-- Order by line number so it's caught if no content is changed but the order of entries is changed
@@ -347,11 +357,11 @@ CREATE VIEW monitor.pg_hba_hash AS
347357
SELECT sha256((string_agg(type||database||user_name||address||netmask||auth_method||options, ','))::bytea) AS sha256_hash
348358
, string_agg(type||database||user_name||address||netmask||auth_method||options, ',') AS hba_string
349359
FROM hba_ordered_list;
350-
-- End view used to create hash of pg_hba
351360

352-
-- Function used to set pg_hba as valid
353361
/*
354-
* This function provides quick, clear interface for resetting the checksum monitor to treat the currently detected configuration as valid after alerting on a change. Note that configuration history will be cleared.
362+
* The `monitor.pg_hba_checksum_set_valid` function provides an interface for resetting the
363+
* checksum monitor.
364+
* Note: configuration history will be cleared.
355365
*/
356366
DROP FUNCTION IF EXISTS monitor.pg_hba_checksum_set_valid();
357367
CREATE FUNCTION monitor.pg_hba_checksum_set_valid() RETURNS smallint
@@ -363,4 +373,3 @@ TRUNCATE monitor.pg_hba_checksum;
363373
SELECT monitor.pg_hba_checksum();
364374

365375
$function$;
366-
-- End function used to set pg_hba as valid

0 commit comments

Comments
 (0)