summaryrefslogtreecommitdiff
path: root/src/mongo/db
diff options
context:
space:
mode:
authorVarun Ravichandran <varun.ravichandran@mongodb.com>2021-01-30 02:01:16 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-02-23 23:30:28 +0000
commit0e1b1f4789c398045052d24f8cceada5e72ed757 (patch)
tree62f88f533daa7a344024ff25045aae22ccc46308 /src/mongo/db
parent14bb3090ba26fe037cf796d406dcf0d23d959f55 (diff)
downloadmongo-0e1b1f4789c398045052d24f8cceada5e72ed757.tar.gz
SERVER-50994: Audit dropCollection, dropIndex, and dropView during dropDatabase on standalones
Diffstat (limited to 'src/mongo/db')
-rw-r--r--src/mongo/db/catalog/database_holder_impl.cpp15
-rw-r--r--src/mongo/db/catalog/database_impl.cpp3
-rw-r--r--src/mongo/db/commands/list_collections.cpp2
-rw-r--r--src/mongo/db/commands/set_feature_compatibility_version_command.cpp2
-rw-r--r--src/mongo/db/commands/validate_db_metadata_cmd.cpp2
-rw-r--r--src/mongo/db/storage/SConscript1
-rw-r--r--src/mongo/db/storage/storage_engine_impl.cpp6
-rw-r--r--src/mongo/db/views/SConscript3
-rw-r--r--src/mongo/db/views/view_catalog.cpp13
-rw-r--r--src/mongo/db/views/view_catalog.h2
-rw-r--r--src/mongo/db/views/view_catalog_test.cpp2
11 files changed, 44 insertions, 7 deletions
diff --git a/src/mongo/db/catalog/database_holder_impl.cpp b/src/mongo/db/catalog/database_holder_impl.cpp
index 7174f87f3b3..b3b81174a77 100644
--- a/src/mongo/db/catalog/database_holder_impl.cpp
+++ b/src/mongo/db/catalog/database_holder_impl.cpp
@@ -39,6 +39,7 @@
#include "mongo/db/catalog/database_impl.h"
#include "mongo/db/concurrency/write_conflict_exception.h"
#include "mongo/db/index_builds_coordinator.h"
+#include "mongo/db/op_observer.h"
#include "mongo/db/operation_context.h"
#include "mongo/db/service_context.h"
#include "mongo/db/stats/top.h"
@@ -215,6 +216,20 @@ void DatabaseHolderImpl::dropDb(OperationContext* opCtx, Database* db) {
break;
}
+ // The in-memory ViewCatalog gets cleared when opObserver::onDropCollection() is called for
+ // the system.views collection. Since it is a replicated collection, this call occurs in
+ // dropCollectionEvenIfSystem(). For standalones, `system.views` and the ViewCatalog are
+ // dropped/cleared here.
+ auto replCoord = repl::ReplicationCoordinator::get(opCtx);
+ if (!replCoord->isReplEnabled() && coll->ns().isSystemDotViews()) {
+ opCtx->getServiceContext()->getOpObserver()->onDropCollection(
+ opCtx,
+ coll->ns(),
+ coll->uuid(),
+ coll->numRecords(opCtx),
+ OpObserver::CollectionDropType::kOnePhase);
+ }
+
Top::get(serviceContext).collectionDropped(coll->ns());
}
diff --git a/src/mongo/db/catalog/database_impl.cpp b/src/mongo/db/catalog/database_impl.cpp
index 60f30b88eb2..ea5ae5568b9 100644
--- a/src/mongo/db/catalog/database_impl.cpp
+++ b/src/mongo/db/catalog/database_impl.cpp
@@ -282,7 +282,8 @@ void DatabaseImpl::getStats(OperationContext* opCtx, BSONObjBuilder* output, dou
return true;
});
- ViewCatalog::get(this)->iterate(opCtx, [&](const ViewDefinition& view) {
+
+ ViewCatalog::get(this)->iterate([&](const ViewDefinition& view) {
nViews += 1;
return true;
});
diff --git a/src/mongo/db/commands/list_collections.cpp b/src/mongo/db/commands/list_collections.cpp
index 7a155f3e780..c8fa5630521 100644
--- a/src/mongo/db/commands/list_collections.cpp
+++ b/src/mongo/db/commands/list_collections.cpp
@@ -375,7 +375,7 @@ public:
ListCollectionsFilter::makeTypeCollectionFilter());
if (!skipViews) {
- viewCatalog->iterate(opCtx, [&](const ViewDefinition& view) {
+ viewCatalog->iterate([&](const ViewDefinition& view) {
if (authorizedCollections &&
!as->isAuthorizedForAnyActionOnResource(
ResourcePattern::forExactNamespace(view.name()))) {
diff --git a/src/mongo/db/commands/set_feature_compatibility_version_command.cpp b/src/mongo/db/commands/set_feature_compatibility_version_command.cpp
index fca17f1d6db..47205b618b6 100644
--- a/src/mongo/db/commands/set_feature_compatibility_version_command.cpp
+++ b/src/mongo/db/commands/set_feature_compatibility_version_command.cpp
@@ -356,7 +356,7 @@ public:
if (!viewCatalog) {
continue;
}
- viewCatalog->iterate(opCtx, [](const ViewDefinition& view) {
+ viewCatalog->iterate([](const ViewDefinition& view) {
uassert(ErrorCodes::CannotDowngrade,
str::stream()
<< "Cannot downgrade the cluster when there are time-series "
diff --git a/src/mongo/db/commands/validate_db_metadata_cmd.cpp b/src/mongo/db/commands/validate_db_metadata_cmd.cpp
index 8af8a44443d..1114f36a379 100644
--- a/src/mongo/db/commands/validate_db_metadata_cmd.cpp
+++ b/src/mongo/db/commands/validate_db_metadata_cmd.cpp
@@ -153,7 +153,7 @@ public:
// If there is no collection name present in the input, run validation against all
// the collections.
if (auto viewCatalog = DatabaseHolder::get(opCtx)->getViewCatalog(opCtx, dbName)) {
- viewCatalog->iterate(opCtx, [this, opCtx](const ViewDefinition& view) {
+ viewCatalog->iterate([this, opCtx](const ViewDefinition& view) {
return _validateView(opCtx, view);
});
}
diff --git a/src/mongo/db/storage/SConscript b/src/mongo/db/storage/SConscript
index 2574035c6f2..28f61230234 100644
--- a/src/mongo/db/storage/SConscript
+++ b/src/mongo/db/storage/SConscript
@@ -572,6 +572,7 @@ env.Library(
'$BUILD_DIR/mongo/db/storage/storage_options',
],
LIBDEPS_PRIVATE=[
+ '$BUILD_DIR/mongo/db/audit',
'$BUILD_DIR/mongo/db/catalog/collection_catalog_helper',
'$BUILD_DIR/mongo/db/resumable_index_builds_idl',
'$BUILD_DIR/mongo/db/storage/storage_repair_observer',
diff --git a/src/mongo/db/storage/storage_engine_impl.cpp b/src/mongo/db/storage/storage_engine_impl.cpp
index 0e8414cb147..6920ad4a2bf 100644
--- a/src/mongo/db/storage/storage_engine_impl.cpp
+++ b/src/mongo/db/storage/storage_engine_impl.cpp
@@ -33,6 +33,7 @@
#include <algorithm>
+#include "mongo/db/audit.h"
#include "mongo/db/catalog/catalog_control.h"
#include "mongo/db/catalog/collection_catalog.h"
#include "mongo/db/catalog/collection_catalog_helper.h"
@@ -797,6 +798,9 @@ Status StorageEngineImpl::_dropCollectionsNoTimestamp(OperationContext* opCtx,
coll->getIndexCatalog()->getIndexIterator(opCtx, true /* includeUnfinishedIndexes */);
while (ii->more()) {
const IndexCatalogEntry* ice = ii->next();
+
+ audit::logDropIndex(&cc(), ice->descriptor()->indexName(), nss.ns());
+
catalog::removeIndex(opCtx,
ice->descriptor()->indexName(),
coll->getCatalogId(),
@@ -805,6 +809,8 @@ Status StorageEngineImpl::_dropCollectionsNoTimestamp(OperationContext* opCtx,
ice->getSharedIdent());
}
+ audit::logDropCollection(&cc(), nss.ns());
+
Status result = catalog::dropCollection(
opCtx, coll->ns(), coll->getCatalogId(), coll->getSharedIdent());
if (!result.isOK() && firstError.isOK()) {
diff --git a/src/mongo/db/views/SConscript b/src/mongo/db/views/SConscript
index 602a5710255..00298b97541 100644
--- a/src/mongo/db/views/SConscript
+++ b/src/mongo/db/views/SConscript
@@ -32,6 +32,9 @@ env.Library(
'$BUILD_DIR/mongo/db/repl/repl_coordinator_interface',
'$BUILD_DIR/mongo/db/timeseries/timeseries_idl',
'resolved_view',
+ ],
+ LIBDEPS_PRIVATE=[
+ '$BUILD_DIR/mongo/db/audit',
]
)
diff --git a/src/mongo/db/views/view_catalog.cpp b/src/mongo/db/views/view_catalog.cpp
index 80cc04f8603..bd35ffd5ddf 100644
--- a/src/mongo/db/views/view_catalog.cpp
+++ b/src/mongo/db/views/view_catalog.cpp
@@ -40,6 +40,7 @@
#include "mongo/base/string_data.h"
#include "mongo/bson/util/builder.h"
#include "mongo/db/api_parameters.h"
+#include "mongo/db/audit.h"
#include "mongo/db/catalog/collection_catalog.h"
#include "mongo/db/catalog/database.h"
#include "mongo/db/namespace_string.h"
@@ -246,6 +247,16 @@ Status ViewCatalog::_reload(OperationContext* opCtx, ViewCatalogLookupBehavior l
void ViewCatalog::clear(const Database* db) {
auto catalog = getViewCatalog(db).writer();
+
+ // First, iterate through the views on this database and audit them before they are dropped.
+ for (auto&& view : catalog->_viewMap) {
+ audit::logDropView(&cc(),
+ (*view.second).name().ns(),
+ (*view.second).viewOn().ns(),
+ (*view.second).pipeline(),
+ ErrorCodes::OK);
+ }
+
catalog.writable()->_viewMap.clear();
catalog.writable()->_viewGraph.clear();
catalog.writable()->_valid = true;
@@ -266,7 +277,7 @@ void ViewCatalog::_requireValidCatalog() const {
_valid);
}
-void ViewCatalog::iterate(OperationContext* opCtx, ViewIteratorCallback callback) const {
+void ViewCatalog::iterate(ViewIteratorCallback callback) const {
_requireValidCatalog();
for (auto&& view : _viewMap) {
if (!callback(*view.second)) {
diff --git a/src/mongo/db/views/view_catalog.h b/src/mongo/db/views/view_catalog.h
index 1b728819bd8..a7752303bc0 100644
--- a/src/mongo/db/views/view_catalog.h
+++ b/src/mongo/db/views/view_catalog.h
@@ -80,7 +80,7 @@ public:
* acquire locks or run for a long time. If the 'callback' returns false, the iterator exists
* early.
*/
- void iterate(OperationContext* opCtx, ViewIteratorCallback callback) const;
+ void iterate(ViewIteratorCallback callback) const;
/**
* Create a new view 'viewName' with contents defined by running the specified aggregation
diff --git a/src/mongo/db/views/view_catalog_test.cpp b/src/mongo/db/views/view_catalog_test.cpp
index 48539c03415..06c859cbcea 100644
--- a/src/mongo/db/views/view_catalog_test.cpp
+++ b/src/mongo/db/views/view_catalog_test.cpp
@@ -649,7 +649,7 @@ TEST_F(ViewCatalogFixture, Iterate) {
std::set<std::string> viewNames = {"db.view1", "db.view2", "db.view3"};
Lock::DBLock dbLock(operationContext(), "db", MODE_IX);
- getViewCatalog()->iterate(operationContext(), [&viewNames](const ViewDefinition& view) {
+ getViewCatalog()->iterate([&viewNames](const ViewDefinition& view) {
std::string name = view.name().toString();
ASSERT(viewNames.end() != viewNames.find(name));
viewNames.erase(name);