blob: 2d4d49688b1fdd57cf3247d1ab54a61ec9d6fa8d [file] [log] [blame]
// Copyright 2017 The Fuchsia 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 <memory>
#include <string>
#include "analyzer/store/bigtable_admin.h"
#include "analyzer/store/bigtable_store.h"
#include "analyzer/store/data_store.h"
#include "analyzer/store/observation_store.h"
#include "analyzer/store/report_store.h"
#include "gflags/gflags.h"
#include "glog/logging.h"
namespace cobalt {
namespace analyzer {
namespace store {
DECLARE_string(bigtable_project_name);
DECLARE_string(bigtable_instance_id);
} // namespace store
} // namespace analyzer
} // namespace cobalt
using cobalt::analyzer::store::BigtableAdmin;
using cobalt::analyzer::store::BigtableStore;
using cobalt::analyzer::store::DataStore;
using cobalt::analyzer::store::FLAGS_bigtable_instance_id;
using cobalt::analyzer::store::FLAGS_bigtable_project_name;
using cobalt::analyzer::store::kOK;
using cobalt::analyzer::store::ObservationStore;
using cobalt::analyzer::store::ReportStore;
DEFINE_string(
command, "create_tables",
"Specify which command to execute. See program help for details.");
DEFINE_uint32(customer, 0, "Customer ID. Used for delete operations.");
DEFINE_uint32(
project, 0,
// This tool is not intended to be used to delete real customer data so
// we do not permit project IDs >= 100.
"Project ID. Used for delete operations. Must be in the range [0, 99]");
DEFINE_uint32(metric, 0, "Which metric to use for delete_observations.");
DEFINE_uint32(report_config, 0,
"Which report config to use for delete_reports.");
DEFINE_bool(
danger_danger_delete_production_reports, false,
"Setting this flag to true will allow you to set project >= 100 "
"when the command is delete_reports, but only in interactive mode.");
bool CreateTablesIfNecessary() {
auto bigtable_admin = BigtableAdmin::CreateFromFlagsOrDie();
return bigtable_admin->CreateTablesIfNecessary();
}
bool DeleteObservationsForMetric(uint32_t customer_id, uint32_t project_id,
uint32_t metric_id) {
ObservationStore observation_store(BigtableStore::CreateFromFlagsOrDie());
return kOK == observation_store.DeleteAllForMetric(customer_id, project_id,
metric_id);
}
bool DeleteReportsForConfig(uint32_t customer_id, uint32_t project_id,
uint32_t report_config_id) {
ReportStore report_store(BigtableStore::CreateFromFlagsOrDie());
return kOK == report_store.DeleteAllForReportConfig(customer_id, project_id,
report_config_id);
}
int main(int argc, char* argv[]) {
google::SetUsageMessage(
"A tool to facilitate working with Cobalt's BigTables in production.\n"
"usage:\n"
"bigtable_tool -command=<command> -bigtable_project_name=<name> "
"-bigtable_instance_id=<name>\n [-customer=<customer_id> "
"-project=<project_id> "
"{-metric=<metric_id>, -report_config=<report_config_id>}]\n"
"commands are:\n"
"create_tables (the default): Creates Cobalt's tables if they don't "
"already exist.\n"
"delete_observations: Permanently delete all data from the "
"Observation Store for the specified metric.\n"
"delete_reports: Permanently delete all data from the Report Store "
"for the specified report config.\n");
google::ParseCommandLineFlags(&argc, &argv, true);
google::InitGoogleLogging(argv[0]);
google::InstallFailureSignalHandler();
if (FLAGS_command == "create_tables") {
if (CreateTablesIfNecessary()) {
std::cout << "create_tables command succeeded.\n";
} else {
std::cout << "create_tables command failed.\n";
}
} else if (FLAGS_command == "delete_observations") {
if (FLAGS_customer * FLAGS_project * FLAGS_metric == 0) {
std::cout << "Invalid Flags: "
"-customer -project -metric must all be specified.\n";
exit(1);
}
if (FLAGS_project >= 100) {
std::cout << "-project=" << FLAGS_project << " is not allowed. ";
std::cout << "Project ID must be less than 100.\n";
std::cout << "This tool is not intended to be used to delete real "
"customer data.\n";
exit(1);
}
if (DeleteObservationsForMetric(FLAGS_customer, FLAGS_project,
FLAGS_metric)) {
std::cout << "delete_observations command succeeded.\n";
} else {
std::cout << "delete_observations command failed.\n";
}
} else if (FLAGS_command == "delete_reports") {
if (FLAGS_customer * FLAGS_project * FLAGS_report_config == 0) {
std::cout << "Invalid flags: "
"-customer -project -report_config must all be specified.\n";
exit(1);
}
if (FLAGS_project >= 100) {
if (FLAGS_danger_danger_delete_production_reports) {
std::cout << std::endl
<< "Bigtable instance: " << FLAGS_bigtable_project_name << "/"
<< FLAGS_bigtable_instance_id << std::endl
<< std::endl;
std::cout << "*WARNING* Project " << FLAGS_project
<< " is a real production project, not a test project.\n";
std::cout
<< "Are you sure you really want to permanently delete all of "
"its report data?\n";
std::cout << "Retype the project ID below to confirm. Anything else to "
"quit.\n";
std::cout << "Project id: ";
std::string response_line;
getline(std::cin, response_line);
uint32_t response = std::stoi(response_line);
if (response != FLAGS_project) {
exit(1);
}
} else {
std::cout << "-project=" << FLAGS_project << " is not allowed. ";
std::cout << "Project ID must be less than 100.\n";
std::cout << "This tool is not intended to be used to delete real "
"customer data.\n";
exit(1);
}
}
if (DeleteReportsForConfig(FLAGS_customer, FLAGS_project,
FLAGS_report_config)) {
std::cout << "delete_reports command succeeded.\n";
} else {
std::cout << "delete_report command failed.\n";
}
} else {
std::cout << "unrecognized command " << FLAGS_command << std::endl;
}
exit(0);
}