diff --git a/src/backend/distributed/commands/role.c b/src/backend/distributed/commands/role.c index 693d428ea..b89f34f55 100644 --- a/src/backend/distributed/commands/role.c +++ b/src/backend/distributed/commands/role.c @@ -570,7 +570,13 @@ GenerateCreateOrAlterRoleCommand(Oid roleOid) completeRoleList = lappend(completeRoleList, DeparseTreeNode(stmt)); } - /* append SECURITY LABEL ON ROLE commands fot this specific user */ + /* + * append SECURITY LABEL ON ROLE commands for this specific user + * When we propagate user creation, we also want to make sure that we propagate + * all the security labels it has been given. For this, we check pg_shseclabel + * for the ROLE entry corresponding to roleOid, and generate the relevant + * SecLabel stmts to be run in the new node. + */ List *secLabelOnRoleStmts = GenerateSecLabelOnRoleStmts(roleOid, rolename); stmt = NULL; foreach_ptr(stmt, secLabelOnRoleStmts) @@ -913,8 +919,6 @@ GenerateGrantRoleStmtsOfRole(Oid roleid) static List * GenerateSecLabelOnRoleStmts(Oid roleid, char *rolename) { - ScanKeyData skey[1]; - HeapTuple tuple = NULL; List *secLabelStmts = NIL; /* @@ -922,11 +926,13 @@ GenerateSecLabelOnRoleStmts(Oid roleid, char *rolename) * security labels are stored in pg_shseclabel instead of pg_seclabel. */ Relation pg_shseclabel = table_open(SharedSecLabelRelationId, AccessShareLock); + ScanKeyData skey[1]; ScanKeyInit(&skey[0], Anum_pg_shseclabel_objoid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(roleid)); SysScanDesc scan = systable_beginscan(pg_shseclabel, SharedSecLabelObjectIndexId, true, NULL, 1, &skey[0]); + HeapTuple tuple = NULL; while (HeapTupleIsValid(tuple = systable_getnext(scan))) { SecLabelStmt *secLabelStmt = makeNode(SecLabelStmt); diff --git a/src/backend/distributed/commands/seclabel.c b/src/backend/distributed/commands/seclabel.c index 67e00a2c4..f3e12ea6e 100644 --- a/src/backend/distributed/commands/seclabel.c +++ b/src/backend/distributed/commands/seclabel.c @@ -11,7 +11,6 @@ #include "postgres.h" -#include "commands/seclabel.h" #include "distributed/commands.h" #include "distributed/commands/utility_hook.h" #include "distributed/coordinator_protocol.h" @@ -20,22 +19,6 @@ #include "distributed/metadata_sync.h" #include "distributed/metadata/distobject.h" - -PG_FUNCTION_INFO_V1(citus_test_register_label_provider); - - -/* - * citus_test_register_label_provider registers a dummy label provider - * named 'citus_tests_label_provider'. This is aimed to be used for testing. - */ -Datum -citus_test_register_label_provider(PG_FUNCTION_ARGS) -{ - register_label_provider("citus_tests_label_provider", citus_test_object_relabel); - PG_RETURN_VOID(); -} - - /* * PreprocessSecLabelStmt is executed before the statement is applied to the local * postgres instance. @@ -54,7 +37,7 @@ PreprocessSecLabelStmt(Node *node, const char *queryString, SecLabelStmt *secLabelStmt = castNode(SecLabelStmt, node); - List *objectAddresses = GetObjectAddressListFromParseTree(node, false, false); + List *objectAddresses = GetObjectAddressListFromParseTree(node, false, true); if (!IsAnyObjectDistributed(objectAddresses)) { return NIL; @@ -64,11 +47,11 @@ PreprocessSecLabelStmt(Node *node, const char *queryString, { if (EnableUnsupportedFeatureMessages) { - ereport(NOTICE, (errmsg("not propagating SECURITY LABEL commands whose" - " object type is not role"), - errhint( - "Connect to worker nodes directly to manually run the same" - " SECURITY LABEL command after disabling DDL propagation."))); + ereport(NOTICE, (errmsg("not propagating SECURITY LABEL commands whose " + "object type is not role"), + errhint("Connect to worker nodes directly to manually " + "run the same SECURITY LABEL command after " + "disabling DDL propagation."))); } return NIL; } diff --git a/src/backend/distributed/operations/shard_rebalancer.c b/src/backend/distributed/operations/shard_rebalancer.c index d339ac56a..213d135e6 100644 --- a/src/backend/distributed/operations/shard_rebalancer.c +++ b/src/backend/distributed/operations/shard_rebalancer.c @@ -317,7 +317,7 @@ PG_FUNCTION_INFO_V1(citus_rebalance_start); PG_FUNCTION_INFO_V1(citus_rebalance_stop); PG_FUNCTION_INFO_V1(citus_rebalance_wait); -bool RunningUnderIsolationTest = false; +bool RunningUnderCitusTestSuite = false; int MaxRebalancerLoggedIgnoredMoves = 5; int RebalancerByDiskSizeBaseCost = 100 * 1024 * 1024; bool PropagateSessionSettingsForLoopbackConnection = false; diff --git a/src/backend/distributed/replication/multi_logical_replication.c b/src/backend/distributed/replication/multi_logical_replication.c index 97f6fdb3d..48571d7c4 100644 --- a/src/backend/distributed/replication/multi_logical_replication.c +++ b/src/backend/distributed/replication/multi_logical_replication.c @@ -1143,7 +1143,7 @@ ConflictWithIsolationTestingBeforeCopy(void) const bool sessionLock = false; const bool dontWait = false; - if (RunningUnderIsolationTest) + if (RunningUnderCitusTestSuite) { SET_LOCKTAG_ADVISORY(tag, MyDatabaseId, SHARD_MOVE_ADVISORY_LOCK_SECOND_KEY, @@ -1177,7 +1177,7 @@ ConflictWithIsolationTestingAfterCopy(void) const bool sessionLock = false; const bool dontWait = false; - if (RunningUnderIsolationTest) + if (RunningUnderCitusTestSuite) { SET_LOCKTAG_ADVISORY(tag, MyDatabaseId, SHARD_MOVE_ADVISORY_LOCK_FIRST_KEY, diff --git a/src/backend/distributed/shared_library_init.c b/src/backend/distributed/shared_library_init.c index 9b5768ee7..639674a25 100644 --- a/src/backend/distributed/shared_library_init.c +++ b/src/backend/distributed/shared_library_init.c @@ -29,6 +29,7 @@ #include "citus_version.h" #include "commands/explain.h" #include "commands/extension.h" +#include "commands/seclabel.h" #include "common/string.h" #include "executor/executor.h" #include "distributed/backend_data.h" @@ -574,6 +575,16 @@ _PG_init(void) INIT_COLUMNAR_SYMBOL(PGFunction, columnar_storage_info); INIT_COLUMNAR_SYMBOL(PGFunction, columnar_store_memory_stats); INIT_COLUMNAR_SYMBOL(PGFunction, test_columnar_storage_write_new_page); + + /* + * This part is only for SECURITY LABEL tests + * mimicking what an actual security label provider would do + */ + if (RunningUnderCitusTestSuite) + { + register_label_provider("citus_tests_label_provider", + citus_test_object_relabel); + } } @@ -2305,13 +2316,14 @@ RegisterCitusConfigVariables(void) WarnIfReplicationModelIsSet, NULL, NULL); DefineCustomBoolVariable( - "citus.running_under_isolation_test", + "citus.running_under_citus_test_suite", gettext_noop( "Only useful for testing purposes, when set to true, Citus does some " - "tricks to implement useful isolation tests with rebalancing. Should " + "tricks to implement useful isolation tests with rebalancing. It also " + "registers a dummy label provider for SECURITY LABEL tests. Should " "never be set to true on production systems "), gettext_noop("for details of the tricks implemented, refer to the source code"), - &RunningUnderIsolationTest, + &RunningUnderCitusTestSuite, false, PGC_SUSET, GUC_SUPERUSER_ONLY | GUC_NO_SHOW_ALL | GUC_NOT_IN_SAMPLE, diff --git a/src/include/distributed/shard_rebalancer.h b/src/include/distributed/shard_rebalancer.h index 38ce4f485..345748ced 100644 --- a/src/include/distributed/shard_rebalancer.h +++ b/src/include/distributed/shard_rebalancer.h @@ -189,7 +189,7 @@ typedef struct RebalancePlanFunctions extern char *VariablesToBePassedToNewConnections; extern int MaxRebalancerLoggedIgnoredMoves; extern int RebalancerByDiskSizeBaseCost; -extern bool RunningUnderIsolationTest; +extern bool RunningUnderCitusTestSuite; extern bool PropagateSessionSettingsForLoopbackConnection; extern int MaxBackgroundTaskExecutorsPerNode; diff --git a/src/test/regress/Makefile b/src/test/regress/Makefile index 4bdc7a1b8..fe4868aa6 100644 --- a/src/test/regress/Makefile +++ b/src/test/regress/Makefile @@ -101,7 +101,7 @@ check-base: all # check-minimal only sets up the cluster check-minimal: all - $(pg_regress_multi_check) --load-extension=citus \ + $(pg_regress_multi_check) --load-extension=citus --seclabel \ -- $(MULTI_REGRESS_OPTS) --schedule=$(citus_abs_srcdir)/minimal_schedule $(EXTRA_TESTS) check-base-vg: all @@ -118,7 +118,7 @@ check-minimal-mx: all -- $(MULTI_REGRESS_OPTS) --schedule=$(citus_abs_srcdir)/mx_minimal_schedule $(EXTRA_TESTS) check-custom-schedule: all - $(pg_regress_multi_check) --load-extension=citus --worker-count=$(WORKERCOUNT) \ + $(pg_regress_multi_check) --load-extension=citus --seclabel-test --worker-count=$(WORKERCOUNT) \ -- $(MULTI_REGRESS_OPTS) --schedule=$(citus_abs_srcdir)/$(SCHEDULE) $(EXTRA_TESTS) check-failure-custom-schedule: all @@ -159,7 +159,7 @@ check-enterprise: all $(pg_regress_multi_check) --load-extension=citus \ -- $(MULTI_REGRESS_OPTS) --schedule=$(citus_abs_srcdir)/enterprise_schedule $(EXTRA_TESTS) check-multi-1: all - $(pg_regress_multi_check) --load-extension=citus \ + $(pg_regress_multi_check) --load-extension=citus --seclabel-test \ -- $(MULTI_REGRESS_OPTS) --schedule=$(citus_abs_srcdir)/multi_1_schedule $(EXTRA_TESTS) check-multi-hyperscale: all diff --git a/src/test/regress/expected/multi_test_helpers.out b/src/test/regress/expected/multi_test_helpers.out index b8758e561..f6200be88 100644 --- a/src/test/regress/expected/multi_test_helpers.out +++ b/src/test/regress/expected/multi_test_helpers.out @@ -526,3 +526,34 @@ BEGIN RETURN result; END; $func$ LANGUAGE plpgsql; +-- Returns pg_seclabels entries from all nodes in the cluster +-- for which the provider is citus_tests_label_provider and the object name is the input +CREATE OR REPLACE FUNCTION get_citus_tests_label_provider_labels(object_name text, + master_port INTEGER DEFAULT 57636, + worker_1_port INTEGER DEFAULT 57637, + worker_2_port INTEGER DEFAULT 57638) +RETURNS TABLE ( + node_type text, + result text +) +AS $func$ +DECLARE + pg_seclabels_cmd TEXT := 'SELECT to_jsonb(q.*) FROM (' || + 'SELECT objtype, label FROM pg_seclabels ' || + 'WHERE provider = ''citus_tests_label_provider'' AND ' || + 'objname = ''' || object_name || ''') q'; +BEGIN + RETURN QUERY + SELECT + CASE + WHEN nodeport = master_port THEN 'coordinator' + WHEN nodeport = worker_1_port THEN 'worker_1' + WHEN nodeport = worker_2_port THEN 'worker_2' + ELSE 'unexpected_node' + END AS node_type, + a.result + FROM run_command_on_all_nodes(pg_seclabels_cmd) a + JOIN pg_dist_node USING (nodeid) + ORDER BY node_type; +END; +$func$ LANGUAGE plpgsql; diff --git a/src/test/regress/expected/seclabel.out b/src/test/regress/expected/seclabel.out index 1920a6f43..3cf2949b6 100644 --- a/src/test/regress/expected/seclabel.out +++ b/src/test/regress/expected/seclabel.out @@ -11,17 +11,6 @@ SELECT citus_remove_node('localhost', :worker_2_port); (1 row) --- now we register a label provider -CREATE FUNCTION citus_test_register_label_provider() - RETURNS void - LANGUAGE C - AS 'citus', $$citus_test_register_label_provider$$; -SELECT citus_test_register_label_provider(); - citus_test_register_label_provider ---------------------------------------------------------------------- - -(1 row) - CREATE ROLE user1; -- check an invalid label for our current dummy hook citus_test_object_relabel SECURITY LABEL ON ROLE user1 IS 'invalid_label'; @@ -29,25 +18,14 @@ ERROR: 'invalid_label' is not a valid security label for Citus tests. -- if we disable metadata_sync, the command will not be propagated SET citus.enable_metadata_sync TO off; SECURITY LABEL ON ROLE user1 IS 'citus_unclassified'; -SELECT objtype, objname, provider, label FROM pg_seclabels; - objtype | objname | provider | label +SELECT node_type, result FROM get_citus_tests_label_provider_labels('user1'); + node_type | result --------------------------------------------------------------------- - role | user1 | citus_tests_label_provider | citus_unclassified -(1 row) - -\c - - - :worker_1_port -SELECT objtype, objname, provider, label FROM pg_seclabels; - objtype | objname | provider | label ---------------------------------------------------------------------- -(0 rows) - -\c - - - :master_port -SELECT citus_test_register_label_provider(); - citus_test_register_label_provider ---------------------------------------------------------------------- - -(1 row) + coordinator | {"label": "citus_unclassified", "objtype": "role"} + worker_1 | +(2 rows) +RESET citus.enable_metadata_sync; -- check that we only support propagating for roles SET citus.shard_replication_factor to 1; CREATE TABLE a (a int); @@ -60,52 +38,14 @@ SELECT create_distributed_table('a', 'a'); SECURITY LABEL ON TABLE a IS 'citus_classified'; NOTICE: not propagating SECURITY LABEL commands whose object type is not role HINT: Connect to worker nodes directly to manually run the same SECURITY LABEL command after disabling DDL propagation. +SELECT node_type, result FROM get_citus_tests_label_provider_labels('a'); + node_type | result +--------------------------------------------------------------------- + coordinator | {"label": "citus_classified", "objtype": "table"} + worker_1 | +(2 rows) + DROP TABLE a; --- the registered label provider is per session only --- this means that we need to maintain the same connection to the worker node --- in order for the label provider to be visible there --- hence here we create the necessary session_level_connection_to_node functions -SET citus.enable_metadata_sync TO off; -CREATE OR REPLACE FUNCTION start_session_level_connection_to_node(text, integer) - RETURNS void - LANGUAGE C STRICT VOLATILE - AS 'citus', $$start_session_level_connection_to_node$$; -CREATE OR REPLACE FUNCTION override_backend_data_gpid(bigint) - RETURNS void - LANGUAGE C STRICT IMMUTABLE - AS 'citus', $$override_backend_data_gpid$$; -SELECT run_command_on_workers($$SET citus.enable_metadata_sync TO off;CREATE OR REPLACE FUNCTION override_backend_data_gpid(bigint) - RETURNS void - LANGUAGE C STRICT IMMUTABLE - AS 'citus'$$); - run_command_on_workers ---------------------------------------------------------------------- - (localhost,57637,t,SET) -(1 row) - -CREATE OR REPLACE FUNCTION run_commands_on_session_level_connection_to_node(text) - RETURNS void - LANGUAGE C STRICT VOLATILE - AS 'citus', $$run_commands_on_session_level_connection_to_node$$; -CREATE OR REPLACE FUNCTION stop_session_level_connection_to_node() - RETURNS void - LANGUAGE C STRICT VOLATILE - AS 'citus', $$stop_session_level_connection_to_node$$; -RESET citus.enable_metadata_sync; --- now we establish a connection to the worker node -SELECT start_session_level_connection_to_node('localhost', :worker_1_port); - start_session_level_connection_to_node ---------------------------------------------------------------------- - -(1 row) - --- with that same connection, we register the label provider in the worker node -SELECT run_commands_on_session_level_connection_to_node('SELECT citus_test_register_label_provider()'); - run_commands_on_session_level_connection_to_node ---------------------------------------------------------------------- - -(1 row) - SET citus.log_remote_commands TO on; SET citus.grep_remote_commands = '%SECURITY LABEL%'; -- then we run a security label statement which will use the same connection to the worker node @@ -120,20 +60,13 @@ SECURITY LABEL for citus_tests_label_provider ON ROLE user1 IS 'citus_unclassifi NOTICE: issuing SECURITY LABEL FOR citus_tests_label_provider ON ROLE user1 IS 'citus_unclassified' DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx RESET citus.log_remote_commands; -SELECT stop_session_level_connection_to_node(); - stop_session_level_connection_to_node +SELECT node_type, result FROM get_citus_tests_label_provider_labels('user1'); + node_type | result --------------------------------------------------------------------- + coordinator | {"label": "citus_unclassified", "objtype": "role"} + worker_1 | {"label": "citus_unclassified", "objtype": "role"} +(2 rows) -(1 row) - -\c - - - :worker_1_port -SELECT objtype, objname, provider, label FROM pg_seclabels; - objtype | objname | provider | label ---------------------------------------------------------------------- - role | user1 | citus_tests_label_provider | citus_unclassified -(1 row) - -\c - - - :master_port -- adding a new node will fail because the label provider is not there -- however, this is enough for testing as we can see that the SECURITY LABEL commands -- will be propagated when adding a new node @@ -142,24 +75,19 @@ SET citus.grep_remote_commands = '%SECURITY LABEL%'; SELECT 1 FROM citus_add_node('localhost', :worker_2_port); NOTICE: issuing SELECT worker_create_or_alter_role('user1', 'CREATE ROLE user1 NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT NOLOGIN NOREPLICATION NOBYPASSRLS CONNECTION LIMIT -1 PASSWORD NULL VALID UNTIL ''infinity''', 'ALTER ROLE user1 NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT NOLOGIN NOREPLICATION NOBYPASSRLS CONNECTION LIMIT -1 PASSWORD NULL VALID UNTIL ''infinity''');SECURITY LABEL FOR citus_tests_label_provider ON ROLE user1 IS 'citus_unclassified' DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx -WARNING: security label provider "citus_tests_label_provider" is not loaded -CONTEXT: while executing command on localhost:xxxxx -ERROR: failure on connection marked as essential: localhost:xxxxx --- cleanup -RESET citus.log_remote_commands; -DROP FUNCTION stop_session_level_connection_to_node, run_commands_on_session_level_connection_to_node, - override_backend_data_gpid, start_session_level_connection_to_node; -SELECT run_command_on_workers($$ DROP FUNCTION override_backend_data_gpid $$); - run_command_on_workers ---------------------------------------------------------------------- - (localhost,57637,t,"DROP FUNCTION") -(1 row) - -DROP FUNCTION citus_test_register_label_provider; -DROP ROLE user1; -SELECT 1 FROM citus_add_node('localhost', :worker_2_port); ?column? --------------------------------------------------------------------- 1 (1 row) +SELECT node_type, result FROM get_citus_tests_label_provider_labels('user1'); + node_type | result +--------------------------------------------------------------------- + coordinator | {"label": "citus_unclassified", "objtype": "role"} + worker_1 | {"label": "citus_unclassified", "objtype": "role"} + worker_2 | {"label": "citus_unclassified", "objtype": "role"} +(3 rows) + +-- cleanup +RESET citus.log_remote_commands; +DROP ROLE user1; diff --git a/src/test/regress/pg_regress_multi.pl b/src/test/regress/pg_regress_multi.pl index 4cc022198..4def6dc79 100755 --- a/src/test/regress/pg_regress_multi.pl +++ b/src/test/regress/pg_regress_multi.pl @@ -50,6 +50,7 @@ sub Usage() print " --connection-timeout Timeout for connecting to worker nodes\n"; print " --mitmproxy Start a mitmproxy for one of the workers\n"; print " --worker-count Number of workers in Citus cluster (default: 2)\n"; + print " --seclabel-test This test runs seclabel propagation tests"; exit 1; } @@ -86,6 +87,7 @@ my $conninfo = ""; my $publicWorker1Host = "localhost"; my $publicWorker2Host = "localhost"; my $workerCount = 2; +my $seclabelTest = 0; my $serversAreShutdown = "TRUE"; my $usingWindows = 0; @@ -120,6 +122,7 @@ GetOptions( 'worker-1-public-hostname=s' => \$publicWorker1Host, 'worker-2-public-hostname=s' => \$publicWorker2Host, 'worker-count=i' => \$workerCount, + 'seclabel-test' => \$seclabelTest, 'help' => sub { Usage() }); my $fixopen = "$bindir/postgres.fixopen"; @@ -560,7 +563,7 @@ if($isolationtester) push(@pgOptions, "citus.metadata_sync_interval=1000"); push(@pgOptions, "citus.metadata_sync_retry_interval=100"); push(@pgOptions, "client_min_messages='warning'"); # pg12 introduced notice showing during isolation tests - push(@pgOptions, "citus.running_under_isolation_test=true"); + push(@pgOptions, "citus.running_under_citus_test_suite=true"); # Disable all features of the maintenance daemon. Otherwise queries might # randomly show temporarily as "waiting..." because they are waiting for the @@ -573,6 +576,14 @@ if($isolationtester) push(@pgOptions, "citus.background_task_queue_interval=-1"); } +# if the security label propagation tests are running in the suite +# we need to load the label provider in PG_init by setting +# running_under_citus_test_suite GUC to true +if($seclabelTest) +{ + push(@pgOptions, "citus.running_under_citus_test_suite=true"); +} + # Add externally added options last, so they overwrite the default ones above for my $option (@userPgOptions) { diff --git a/src/test/regress/sql/multi_test_helpers.sql b/src/test/regress/sql/multi_test_helpers.sql index f7c97f1b2..3e7c0fbda 100644 --- a/src/test/regress/sql/multi_test_helpers.sql +++ b/src/test/regress/sql/multi_test_helpers.sql @@ -550,3 +550,35 @@ BEGIN RETURN result; END; $func$ LANGUAGE plpgsql; + +-- Returns pg_seclabels entries from all nodes in the cluster +-- for which the provider is citus_tests_label_provider and the object name is the input +CREATE OR REPLACE FUNCTION get_citus_tests_label_provider_labels(object_name text, + master_port INTEGER DEFAULT 57636, + worker_1_port INTEGER DEFAULT 57637, + worker_2_port INTEGER DEFAULT 57638) +RETURNS TABLE ( + node_type text, + result text +) +AS $func$ +DECLARE + pg_seclabels_cmd TEXT := 'SELECT to_jsonb(q.*) FROM (' || + 'SELECT objtype, label FROM pg_seclabels ' || + 'WHERE provider = ''citus_tests_label_provider'' AND ' || + 'objname = ''' || object_name || ''') q'; +BEGIN + RETURN QUERY + SELECT + CASE + WHEN nodeport = master_port THEN 'coordinator' + WHEN nodeport = worker_1_port THEN 'worker_1' + WHEN nodeport = worker_2_port THEN 'worker_2' + ELSE 'unexpected_node' + END AS node_type, + a.result + FROM run_command_on_all_nodes(pg_seclabels_cmd) a + JOIN pg_dist_node USING (nodeid) + ORDER BY node_type; +END; +$func$ LANGUAGE plpgsql; diff --git a/src/test/regress/sql/seclabel.sql b/src/test/regress/sql/seclabel.sql index 7176da96b..b6f7980f2 100644 --- a/src/test/regress/sql/seclabel.sql +++ b/src/test/regress/sql/seclabel.sql @@ -8,13 +8,6 @@ -- citus_add_node later SELECT citus_remove_node('localhost', :worker_2_port); --- now we register a label provider -CREATE FUNCTION citus_test_register_label_provider() - RETURNS void - LANGUAGE C - AS 'citus', $$citus_test_register_label_provider$$; -SELECT citus_test_register_label_provider(); - CREATE ROLE user1; -- check an invalid label for our current dummy hook citus_test_object_relabel @@ -23,54 +16,18 @@ SECURITY LABEL ON ROLE user1 IS 'invalid_label'; -- if we disable metadata_sync, the command will not be propagated SET citus.enable_metadata_sync TO off; SECURITY LABEL ON ROLE user1 IS 'citus_unclassified'; -SELECT objtype, objname, provider, label FROM pg_seclabels; +SELECT node_type, result FROM get_citus_tests_label_provider_labels('user1'); -\c - - - :worker_1_port -SELECT objtype, objname, provider, label FROM pg_seclabels; - -\c - - - :master_port -SELECT citus_test_register_label_provider(); +RESET citus.enable_metadata_sync; -- check that we only support propagating for roles SET citus.shard_replication_factor to 1; CREATE TABLE a (a int); SELECT create_distributed_table('a', 'a'); SECURITY LABEL ON TABLE a IS 'citus_classified'; +SELECT node_type, result FROM get_citus_tests_label_provider_labels('a'); DROP TABLE a; --- the registered label provider is per session only --- this means that we need to maintain the same connection to the worker node --- in order for the label provider to be visible there --- hence here we create the necessary session_level_connection_to_node functions -SET citus.enable_metadata_sync TO off; -CREATE OR REPLACE FUNCTION start_session_level_connection_to_node(text, integer) - RETURNS void - LANGUAGE C STRICT VOLATILE - AS 'citus', $$start_session_level_connection_to_node$$; -CREATE OR REPLACE FUNCTION override_backend_data_gpid(bigint) - RETURNS void - LANGUAGE C STRICT IMMUTABLE - AS 'citus', $$override_backend_data_gpid$$; -SELECT run_command_on_workers($$SET citus.enable_metadata_sync TO off;CREATE OR REPLACE FUNCTION override_backend_data_gpid(bigint) - RETURNS void - LANGUAGE C STRICT IMMUTABLE - AS 'citus'$$); -CREATE OR REPLACE FUNCTION run_commands_on_session_level_connection_to_node(text) - RETURNS void - LANGUAGE C STRICT VOLATILE - AS 'citus', $$run_commands_on_session_level_connection_to_node$$; -CREATE OR REPLACE FUNCTION stop_session_level_connection_to_node() - RETURNS void - LANGUAGE C STRICT VOLATILE - AS 'citus', $$stop_session_level_connection_to_node$$; -RESET citus.enable_metadata_sync; - --- now we establish a connection to the worker node -SELECT start_session_level_connection_to_node('localhost', :worker_1_port); - --- with that same connection, we register the label provider in the worker node -SELECT run_commands_on_session_level_connection_to_node('SELECT citus_test_register_label_provider()'); - SET citus.log_remote_commands TO on; SET citus.grep_remote_commands = '%SECURITY LABEL%'; @@ -81,12 +38,8 @@ SECURITY LABEL for citus_tests_label_provider ON ROLE user1 IS NULL; SECURITY LABEL for citus_tests_label_provider ON ROLE user1 IS 'citus_unclassified'; RESET citus.log_remote_commands; -SELECT stop_session_level_connection_to_node(); -\c - - - :worker_1_port -SELECT objtype, objname, provider, label FROM pg_seclabels; - -\c - - - :master_port +SELECT node_type, result FROM get_citus_tests_label_provider_labels('user1'); -- adding a new node will fail because the label provider is not there -- however, this is enough for testing as we can see that the SECURITY LABEL commands @@ -95,11 +48,8 @@ SET citus.log_remote_commands TO on; SET citus.grep_remote_commands = '%SECURITY LABEL%'; SELECT 1 FROM citus_add_node('localhost', :worker_2_port); +SELECT node_type, result FROM get_citus_tests_label_provider_labels('user1'); + -- cleanup RESET citus.log_remote_commands; -DROP FUNCTION stop_session_level_connection_to_node, run_commands_on_session_level_connection_to_node, - override_backend_data_gpid, start_session_level_connection_to_node; -SELECT run_command_on_workers($$ DROP FUNCTION override_backend_data_gpid $$); -DROP FUNCTION citus_test_register_label_provider; DROP ROLE user1; -SELECT 1 FROM citus_add_node('localhost', :worker_2_port);