Merged PR 2081022: NameSpace Validation for config db · documentdb/documentdb@c0cdc8c · GitHub
Skip to content

Commit c0cdc8c

Browse files
LordParagguanzhousongmicrosoft
authored andcommitted
Merged PR 2081022: NameSpace Validation for config db
### Does this PR have any customer impact? ### Type (Feature, Refactoring, Bugfix, DevOps, Testing, Perf, etc) ### Does it involve schema level changes? (Table, Column, Index, UDF, etc level changes) ### Are you introducing any new config? If yes, do you have tests with and without them being set? ### ChangeLog (Refer [Template](../oss/CHANGELOG.md)) ### Description NameSpace Validation for config and admin db ---- #### AI description (iteration 1) #### PR Classification New feature: Adds namespace validation to restrict operations on reserved system databases (`config` and `admin`), with a feature flag to control index creation permissions. #### PR Summary This PR introduces namespace validation to prevent users from creating, dropping, or modifying reserved collections in system databases (`config` and `admin`), with configurable controls for index creation. The implementation includes comprehensive test coverage and is controlled by feature flags for gradual rollout. - **`/oss/pg_documentdb/src/metadata/collection.c`**: Added `ValidateSystemNamespace()` function to restrict operations on reserved collection names (e.g., `chunks`, `shards`, `version`) in the `config` database - **`/oss/pg_documentdb/src/commands/`**: Integrated validation checks in `create_collection_core.c`, `drop_collection.c`, and `create_collection_view.c` to enforce namespace restrictions - **`/gateway/managed/Mongo.Service.Postgres/`**: Added `EnableIndexCreationConfigDB` configuration flag in `PostgresTenantConfiguration.cs` and updated `PostgresMongoClient.cs` to conditionally allow index creation on system databases - **`/oss/pg_documentdb/src/configs/feature_flag_configs.c`**: Introduced `enableNewNamespaceValidation` feature flag with default value `false` for controlled rollout - **Test files**: Added comprehensive integration tests in `CreateIndexSystemDbTests.cs` and regression tests in `commands_admin_config_db_validation.sql` to validate both restricted and allowed operations <!-- GitOpsUserAgent=GitOps.Apps.Server.pullrequestcopilot --> Signed-off-by: Parag Jain <paragjain@microsoft.com>
1 parent aa6a5da commit c0cdc8c

9 files changed

Lines changed: 585 additions & 4 deletions

File tree

‎pg_documentdb/src/commands/drop_collection.c‎

Lines changed: 11 additions & 2 deletions

‎pg_documentdb/src/commands/rename_collection.c‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
#include "commands/parse_error.h"
2727
#include "commands/rename_collection.h"
2828

29+
extern bool EnableNewNamespaceValidation;
30+
2931
static void DropMongoCollection(char *, char *);
3032
static void UpdateMongoCollectionName(char *, char *, char *);
3133

@@ -139,6 +141,12 @@ ExecuteRenameCollection(char *databaseName, char *sourceCollectionName,
139141
Datum collection_datum = CStringGetTextDatum(sourceCollectionName);
140142
Datum new_collection_datum = CStringGetTextDatum(targetCollectionName);
141143

144+
if (EnableNewNamespaceValidation)
145+
{
146+
StringView collectionView = CreateStringViewFromString(sourceCollectionName);
147+
ValidateCollectionNameForValidSystemNamespace(&collectionView, database_datum);
148+
}
149+
142150
/*
143151
* Check if the collection to be updated exists. if not, throw an error.
144152
*/

‎pg_documentdb/src/configs/feature_flag_configs.c‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,11 @@ bool EnableOnlyCollectionCacheInvalidateOnCollectionChanges =
449449
bool EnableStreamingCursorDrainViaDestReceiver =
450450
DEFAULT_ENABLE_STREAMING_CURSOR_DRAIN_VIA_DESTRECEIVER;
451451

452+
/* Added in v112, Pending stabilization, enable in v113 */
453+
#define DEFAULT_ENABLE_NEW_NAMESPACE_VALIDATION false
454+
bool EnableNewNamespaceValidation =
455+
DEFAULT_ENABLE_NEW_NAMESPACE_VALIDATION;
456+
452457
/*
453458
* SECTION: Changestream feature flags
454459
*/
@@ -1187,4 +1192,12 @@ InitializeFeatureFlagConfigurations(const char *prefix, const char *newGucPrefix
11871192
NULL, &EnableDuplicateFieldFix,
11881193
DEFAULT_ENABLE_DUPLICATE_FIELD_FIX,
11891194
PGC_USERSET, 0, NULL, NULL, NULL);
1195+
1196+
DefineCustomBoolVariable(
1197+
psprintf("%s.enableNewNamespaceValidation", newGucPrefix),
1198+
gettext_noop(
1199+
"Whether to enable new namespace validation."),
1200+
NULL, &EnableNewNamespaceValidation,
1201+
DEFAULT_ENABLE_NEW_NAMESPACE_VALIDATION,
1202+
PGC_USERSET, 0, NULL, NULL, NULL);
11901203
}

‎pg_documentdb/src/metadata/collection.c‎

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ extern bool ForceLocalExecutionShardQueries;
109109
extern bool EnableSchemaValidation;
110110
extern int MaxSchemaValidatorSize;
111111
extern bool EnableOnlyCollectionCacheInvalidateOnCollectionChanges;
112+
extern bool EnableNewNamespaceValidation;
112113

113114
/* user-defined functions */
114115
PG_FUNCTION_INFO_V1(command_collection_table);
@@ -140,6 +141,7 @@ static void UpdateCollectionOptions(MongoCollection *collection, const
140141
pgbson *updateSpec);
141142
static void RemoveCollectionOptions(MongoCollection *collection, const
142143
pgbson *removeSpec);
144+
static void ValidateSystemNamespace(const char *databaseName, const char *collectionName);
143145

144146

145147
/*
@@ -1334,12 +1336,12 @@ void
13341336
ValidateCollectionNameForValidSystemNamespace(StringView *collectionView,
13351337
Datum databaseNameDatum)
13361338
{
1339+
char *collectionName = CreateStringFromStringView(collectionView);
13371340
if (StringViewStartsWithStringView(collectionView, &SystemPrefix))
13381341
{
13391342
bool found = false;
13401343
for (int i = 0; i < ValidSystemCollectionNamesLength; i++)
13411344
{
1342-
char *collectionName = CreateStringFromStringView(collectionView);
13431345
if (strcmp(collectionName, ValidSystemCollectionNames[i]) == 0)
13441346
{
13451347
found = true;
@@ -1361,6 +1363,50 @@ ValidateCollectionNameForValidSystemNamespace(StringView *collectionView,
13611363
collectionView->length, collectionView->string)));
13621364
}
13631365
}
1366+
1367+
if (EnableNewNamespaceValidation)
1368+
{
1369+
ValidateSystemNamespace(text_to_cstring(DatumGetTextP(databaseNameDatum)),
1370+
collectionName);
1371+
}
1372+
}
1373+
1374+
1375+
static int
1376+
CompareStringPointers(const void *a, const void *b)
1377+
{
1378+
const char *key = *(const char **) a;
1379+
const char *elem = *(const char **) b;
1380+
return strcmp(key, elem);
1381+
}
1382+
1383+
1384+
/*
1385+
* this function restricts the usage of certain namespaces that are reserved for internal use.
1386+
* For example, we reserve the 'config' database for internal use and disallow users from creating collections with certain names in that database.
1387+
* TODO : add restrictions for 'admin' and 'local' database
1388+
*/
1389+
static void
1390+
ValidateSystemNamespace(const char *databaseName, const char *collectionName)
1391+
{
1392+
/* restrict limited collection in 'config' db (sorted for bsearch) */
1393+
const char *limitedConfigCollections[] = {
1394+
"_shards", "chunks", "collections", "databases", "settings", "shards", "version"
1395+
};
1396+
const int limitedConfigCollectionsLength = sizeof(limitedConfigCollections) /
1397+
sizeof(char *);
1398+
if (strcmp(databaseName, "config") == 0)
1399+
{
1400+
if (bsearch(&collectionName, limitedConfigCollections,
1401+
limitedConfigCollectionsLength, sizeof(const char *),
1402+
CompareStringPointers) != NULL)
1403+
{
1404+
ereport(ERROR, (errcode(ERRCODE_DOCUMENTDB_ILLEGALOPERATION),
1405+
errmsg(
1406+
"The namespace %s.%s is reserved and cannot be used",
1407+
databaseName, collectionName)));
1408+
}
1409+
}
13641410
}
13651411

13661412

‎pg_documentdb/src/test/regress/basic_schedule‎

Lines changed: 1 addition & 0 deletions

0 commit comments

Comments
 (0)