mirror of https://github.com/citusdata/citus.git
addressing reviews
parent
53075d4352
commit
91353d3b2b
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue