foundationdb/fdbcli/AuditStorageCommand.actor.cpp

133 lines
4.7 KiB
C++

/*
* AuditStorageCommand.actor.cpp
*
* This source file is part of the FoundationDB open source project
*
* Copyright 2013-2023 Apple Inc. and the FoundationDB project authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "fdbcli/fdbcli.actor.h"
#include "fdbclient/IClientApi.h"
#include "fdbclient/ManagementAPI.actor.h"
#include "fdbclient/Audit.h"
#include "flow/Arena.h"
#include "flow/FastRef.h"
#include "flow/ThreadHelper.actor.h"
#include "flow/actorcompiler.h" // This must be the last #include.
namespace fdb_cli {
ACTOR Future<UID> auditStorageCommandActor(Reference<IClusterConnectionRecord> clusterFile,
std::vector<StringRef> tokens) {
if (tokens.size() < 2) {
printUsage(tokens[0]);
return UID();
}
state UID resAuditId;
if (tokencmp(tokens[1], "cancel")) {
if (tokens.size() != 4) {
printUsage(tokens[0]);
return UID();
}
AuditType type = AuditType::Invalid;
if (tokencmp(tokens[2], "ha")) {
type = AuditType::ValidateHA;
} else if (tokencmp(tokens[2], "replica")) {
type = AuditType::ValidateReplica;
} else if (tokencmp(tokens[2], "locationmetadata")) {
type = AuditType::ValidateLocationMetadata;
} else if (tokencmp(tokens[2], "ssshard")) {
type = AuditType::ValidateStorageServerShard;
} else {
printUsage(tokens[0]);
return UID();
}
const UID auditId = UID::fromString(tokens[3].toString());
UID cancelledAuditId = wait(cancelAuditStorage(clusterFile, type, auditId, /*timeoutSeconds=*/60));
resAuditId = cancelledAuditId;
} else {
AuditType type = AuditType::Invalid;
if (tokencmp(tokens[1], "ha")) {
type = AuditType::ValidateHA;
} else if (tokencmp(tokens[1], "replica")) {
type = AuditType::ValidateReplica;
} else if (tokencmp(tokens[1], "locationmetadata")) {
type = AuditType::ValidateLocationMetadata;
} else if (tokencmp(tokens[1], "ssshard")) {
type = AuditType::ValidateStorageServerShard;
} else {
printUsage(tokens[0]);
return UID();
}
Key begin = allKeys.begin, end = allKeys.end;
if (tokens.size() == 3) {
begin = tokens[2];
} else if (tokens.size() == 4 || tokens.size() == 5) {
begin = tokens[2];
end = tokens[3];
} else {
printUsage(tokens[0]);
return UID();
}
if (end > allKeys.end) {
printUsage(tokens[0]);
return UID();
}
if (begin >= end) {
printUsage(tokens[0]);
return UID();
}
KeyValueStoreType engineType = KeyValueStoreType::END;
if (tokens.size() == 5 && (type == AuditType::ValidateHA || type == AuditType::ValidateReplica)) {
engineType = KeyValueStoreType::fromString(tokens[4].toString());
if (engineType != KeyValueStoreType::SSD_BTREE_V2 && engineType != KeyValueStoreType::SSD_ROCKSDB_V1 &&
engineType != KeyValueStoreType::SSD_SHARDED_ROCKSDB) {
printUsage(tokens[0]);
return UID();
}
}
// For KeyValueStoreType::END: do not specify any storage engine
// Every storage engine will be audited
UID startedAuditId =
wait(auditStorage(clusterFile, KeyRangeRef(begin, end), type, engineType, /*timeoutSeconds=*/60));
resAuditId = startedAuditId;
}
return resAuditId;
}
CommandFactory auditStorageFactory(
"audit_storage",
CommandHelp("audit_storage <Type> [BeginKey EndKey] <EngineType>",
"Start an audit storage",
"Specify audit `Type' (only `ha' and `replica' and `locationmetadata' and "
"`ssshard' `Type' are supported currently), and\n"
"optionally a sub-range with `BeginKey' and `EndKey'.\n"
"Specify audit `EngineType' when auditType is `ha' or `replica'\n"
"(only `ssd-rocksdb-v1' and `ssd-sharded-rocksdb' and `ssd-2' are supported).\n"
"If no EngineType is specified, every storage engine will be audited.\n"
"For example, to audit the full key range: `audit_storage ha'\n"
"To audit a sub-range only: `audit_storage ha \\xa \\xb'\n"
"Returns an audit `ID'. See also `get_audit_status' command.\n"
"Note that BeginKey should not equal to EndKey and EndKey is at most \\xff.\n"
"To cancel an audit: audit_storage cancel <Type> [ID]"));
} // namespace fdb_cli