YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/Users/deen/code/yugabyte-db/src/yb/tools/yb-admin_client.cc
Line
Count
Source (jump to first uncovered line)
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
//
18
// The following only applies to changes made to this file as part of YugaByte development.
19
//
20
// Portions Copyright (c) YugaByte, Inc.
21
//
22
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
23
// in compliance with the License.  You may obtain a copy of the License at
24
//
25
// http://www.apache.org/licenses/LICENSE-2.0
26
//
27
// Unless required by applicable law or agreed to in writing, software distributed under the License
28
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
29
// or implied.  See the License for the specific language governing permissions and limitations
30
// under the License.
31
//
32
33
#include "yb/tools/yb-admin_client.h"
34
35
#include <sstream>
36
#include <type_traits>
37
38
#include <boost/multi_index/composite_key.hpp>
39
#include <boost/multi_index/global_fun.hpp>
40
#include <boost/multi_index/ordered_index.hpp>
41
#include <boost/multi_index_container.hpp>
42
#include <boost/tti/has_member_function.hpp>
43
#include <google/protobuf/util/json_util.h>
44
#include <gtest/gtest.h>
45
46
#include "yb/client/client.h"
47
#include "yb/client/table.h"
48
#include "yb/client/table_creator.h"
49
#include "yb/client/table_alterer.h"
50
#include "yb/client/table_info.h"
51
52
#include "yb/common/json_util.h"
53
#include "yb/common/redis_constants_common.h"
54
#include "yb/common/transaction.h"
55
#include "yb/common/wire_protocol.h"
56
57
#include "yb/consensus/consensus.proxy.h"
58
59
#include "yb/gutil/strings/join.h"
60
#include "yb/gutil/strings/numbers.h"
61
#include "yb/gutil/strings/split.h"
62
63
#include "yb/master/master_admin.proxy.h"
64
#include "yb/master/master_backup.proxy.h"
65
#include "yb/master/master_client.proxy.h"
66
#include "yb/master/master_cluster.proxy.h"
67
#include "yb/master/master_ddl.proxy.h"
68
#include "yb/master/master_encryption.proxy.h"
69
#include "yb/master/master_replication.proxy.h"
70
#include "yb/master/master_defaults.h"
71
#include "yb/master/sys_catalog.h"
72
73
#include "yb/rpc/messenger.h"
74
#include "yb/rpc/proxy.h"
75
76
#include "yb/tserver/tserver_admin.proxy.h"
77
#include "yb/tserver/tserver_service.proxy.h"
78
79
#include "yb/util/format.h"
80
#include "yb/util/net/net_util.h"
81
#include "yb/util/protobuf_util.h"
82
#include "yb/util/random_util.h"
83
#include "yb/util/status_format.h"
84
#include "yb/util/stol_utils.h"
85
#include "yb/util/string_case.h"
86
#include "yb/util/string_util.h"
87
88
DEFINE_bool(wait_if_no_leader_master, false,
89
            "When yb-admin connects to the cluster and no leader master is present, "
90
            "this flag determines if yb-admin should wait for the entire duration of timeout or"
91
            "in case a leader master appears in that duration or return error immediately.");
92
93
DEFINE_string(certs_dir_name, "",
94
              "Directory with certificates to use for secure server connection.");
95
96
DEFINE_string(client_node_name, "", "Client node name.");
97
98
DEFINE_bool(
99
    disable_graceful_transition, false,
100
    "During a leader stepdown, disable graceful leadership transfer "
101
    "to an up to date peer");
102
103
// Maximum number of elements to dump on unexpected errors.
104
static constexpr int MAX_NUM_ELEMENTS_TO_SHOW_ON_ERROR = 10;
105
106
PB_ENUM_FORMATTERS(yb::PeerRole);
107
PB_ENUM_FORMATTERS(yb::AppStatusPB::ErrorCode);
108
PB_ENUM_FORMATTERS(yb::tablet::RaftGroupStatePB);
109
110
namespace yb {
111
namespace tools {
112
113
using namespace std::literals;
114
115
using std::cout;
116
using std::endl;
117
118
using google::protobuf::RepeatedPtrField;
119
using google::protobuf::util::MessageToJsonString;
120
121
using client::YBClientBuilder;
122
using client::YBTableName;
123
using rpc::MessengerBuilder;
124
using rpc::RpcController;
125
using strings::Substitute;
126
using tserver::TabletServerServiceProxy;
127
using tserver::TabletServerAdminServiceProxy;
128
using tserver::UpgradeYsqlRequestPB;
129
using tserver::UpgradeYsqlResponsePB;
130
131
using consensus::ConsensusServiceProxy;
132
using consensus::LeaderStepDownRequestPB;
133
using consensus::LeaderStepDownResponsePB;
134
using consensus::RaftPeerPB;
135
using consensus::RunLeaderElectionRequestPB;
136
using consensus::RunLeaderElectionResponsePB;
137
138
using master::ListMastersRequestPB;
139
using master::ListMastersResponsePB;
140
using master::ListMasterRaftPeersRequestPB;
141
using master::ListMasterRaftPeersResponsePB;
142
using master::ListTabletServersRequestPB;
143
using master::ListTabletServersResponsePB;
144
using master::ListLiveTabletServersRequestPB;
145
using master::ListLiveTabletServersResponsePB;
146
using master::TabletLocationsPB;
147
using master::TSInfoPB;
148
149
namespace {
150
151
static constexpr const char* kRpcHostPortHeading = "RPC Host/Port";
152
static constexpr const char* kDBTypePrefixUnknown = "unknown";
153
static constexpr const char* kDBTypePrefixCql = "ycql";
154
static constexpr const char* kDBTypePrefixYsql = "ysql";
155
static constexpr const char* kDBTypePrefixRedis = "yedis";
156
static constexpr const char* kTableIDPrefix = "tableid";
157
158
string FormatFirstHostPort(
159
36
    const RepeatedPtrField<HostPortPB>& rpc_addresses) {
160
36
  if (rpc_addresses.empty()) {
161
0
    return "N/A";
162
36
  } else {
163
36
    return HostPortPBToString(rpc_addresses.Get(0));
164
36
  }
165
36
}
166
167
0
string FormatDouble(double d, int precision = 2) {
168
0
  std::ostringstream op_stream;
169
0
  op_stream << std::fixed << std::setprecision(precision);
170
0
  op_stream << d;
171
0
  return op_stream.str();
172
0
}
173
174
const int kPartitionRangeColWidth = 56;
175
const int kHostPortColWidth = 20;
176
const int kTableNameColWidth = 48;
177
const int kNumCharactersInUuid = 32;
178
const int kLongColWidth = 15;
179
const int kSmallColWidth = 8;
180
const int kSleepTimeSec = 1;
181
const int kNumberOfTryouts = 30;
182
183
BOOST_TTI_HAS_MEMBER_FUNCTION(has_error)
184
template<typename T>
185
constexpr bool HasMemberFunctionHasError = has_member_function_has_error<const T, bool>::value;
186
187
template<class Response>
188
Result<Response> ResponseResult(Response&& response,
189
206
    typename std::enable_if<HasMemberFunctionHasError<Response>, void*>::type = nullptr) {
190
  // Response has has_error method, use status from it
191
206
  if(response.has_error()) {
192
0
    return StatusFromPB(response.error().status());
193
0
  }
194
206
  return std::move(response);
195
206
}
yb-admin_client.cc:yb::Result<yb::master::ListMastersResponsePB> yb::tools::(anonymous namespace)::ResponseResult<yb::master::ListMastersResponsePB>(yb::master::ListMastersResponsePB&&, std::__1::enable_if<HasMemberFunctionHasError<yb::master::ListMastersResponsePB>, void*>::type)
Line
Count
Source
189
18
    typename std::enable_if<HasMemberFunctionHasError<Response>, void*>::type = nullptr) {
190
  // Response has has_error method, use status from it
191
18
  if(response.has_error()) {
192
0
    return StatusFromPB(response.error().status());
193
0
  }
194
18
  return std::move(response);
195
18
}
Unexecuted instantiation: yb-admin_client.cc:yb::Result<yb::consensus::RunLeaderElectionResponsePB> yb::tools::(anonymous namespace)::ResponseResult<yb::consensus::RunLeaderElectionResponsePB>(yb::consensus::RunLeaderElectionResponsePB&&, std::__1::enable_if<HasMemberFunctionHasError<yb::consensus::RunLeaderElectionResponsePB>, void*>::type)
yb-admin_client.cc:yb::Result<yb::consensus::ChangeConfigResponsePB> yb::tools::(anonymous namespace)::ResponseResult<yb::consensus::ChangeConfigResponsePB>(yb::consensus::ChangeConfigResponsePB&&, std::__1::enable_if<HasMemberFunctionHasError<yb::consensus::ChangeConfigResponsePB>, void*>::type)
Line
Count
Source
189
3
    typename std::enable_if<HasMemberFunctionHasError<Response>, void*>::type = nullptr) {
190
  // Response has has_error method, use status from it
191
3
  if(response.has_error()) {
192
0
    return StatusFromPB(response.error().status());
193
0
  }
194
3
  return std::move(response);
195
3
}
Unexecuted instantiation: yb-admin_client.cc:yb::Result<yb::master::DumpMasterStateResponsePB> yb::tools::(anonymous namespace)::ResponseResult<yb::master::DumpMasterStateResponsePB>(yb::master::DumpMasterStateResponsePB&&, std::__1::enable_if<HasMemberFunctionHasError<yb::master::DumpMasterStateResponsePB>, void*>::type)
Unexecuted instantiation: yb-admin_client.cc:yb::Result<yb::master::GetLoadMovePercentResponsePB> yb::tools::(anonymous namespace)::ResponseResult<yb::master::GetLoadMovePercentResponsePB>(yb::master::GetLoadMovePercentResponsePB&&, std::__1::enable_if<HasMemberFunctionHasError<yb::master::GetLoadMovePercentResponsePB>, void*>::type)
yb-admin_client.cc:yb::Result<yb::master::GetTabletLocationsResponsePB> yb::tools::(anonymous namespace)::ResponseResult<yb::master::GetTabletLocationsResponsePB>(yb::master::GetTabletLocationsResponsePB&&, std::__1::enable_if<HasMemberFunctionHasError<yb::master::GetTabletLocationsResponsePB>, void*>::type)
Line
Count
Source
189
134
    typename std::enable_if<HasMemberFunctionHasError<Response>, void*>::type = nullptr) {
190
  // Response has has_error method, use status from it
191
134
  if(response.has_error()) {
192
0
    return StatusFromPB(response.error().status());
193
0
  }
194
134
  return std::move(response);
195
134
}
yb-admin_client.cc:yb::Result<yb::master::ListTabletServersResponsePB> yb::tools::(anonymous namespace)::ResponseResult<yb::master::ListTabletServersResponsePB>(yb::master::ListTabletServersResponsePB&&, std::__1::enable_if<HasMemberFunctionHasError<yb::master::ListTabletServersResponsePB>, void*>::type)
Line
Count
Source
189
1
    typename std::enable_if<HasMemberFunctionHasError<Response>, void*>::type = nullptr) {
190
  // Response has has_error method, use status from it
191
1
  if(response.has_error()) {
192
0
    return StatusFromPB(response.error().status());
193
0
  }
194
1
  return std::move(response);
195
1
}
yb-admin_client.cc:yb::Result<yb::master::LaunchBackfillIndexForTableResponsePB> yb::tools::(anonymous namespace)::ResponseResult<yb::master::LaunchBackfillIndexForTableResponsePB>(yb::master::LaunchBackfillIndexForTableResponsePB&&, std::__1::enable_if<HasMemberFunctionHasError<yb::master::LaunchBackfillIndexForTableResponsePB>, void*>::type)
Line
Count
Source
189
1
    typename std::enable_if<HasMemberFunctionHasError<Response>, void*>::type = nullptr) {
190
  // Response has has_error method, use status from it
191
1
  if(response.has_error()) {
192
0
    return StatusFromPB(response.error().status());
193
0
  }
194
1
  return std::move(response);
195
1
}
Unexecuted instantiation: yb-admin_client.cc:yb::Result<yb::master::ChangeLoadBalancerStateResponsePB> yb::tools::(anonymous namespace)::ResponseResult<yb::master::ChangeLoadBalancerStateResponsePB>(yb::master::ChangeLoadBalancerStateResponsePB&&, std::__1::enable_if<HasMemberFunctionHasError<yb::master::ChangeLoadBalancerStateResponsePB>, void*>::type)
Unexecuted instantiation: yb-admin_client.cc:yb::Result<yb::master::GetLoadBalancerStateResponsePB> yb::tools::(anonymous namespace)::ResponseResult<yb::master::GetLoadBalancerStateResponsePB>(yb::master::GetLoadBalancerStateResponsePB&&, std::__1::enable_if<HasMemberFunctionHasError<yb::master::GetLoadBalancerStateResponsePB>, void*>::type)
Unexecuted instantiation: yb-admin_client.cc:yb::Result<yb::master::FlushSysCatalogResponsePB> yb::tools::(anonymous namespace)::ResponseResult<yb::master::FlushSysCatalogResponsePB>(yb::master::FlushSysCatalogResponsePB&&, std::__1::enable_if<HasMemberFunctionHasError<yb::master::FlushSysCatalogResponsePB>, void*>::type)
Unexecuted instantiation: yb-admin_client.cc:yb::Result<yb::master::CompactSysCatalogResponsePB> yb::tools::(anonymous namespace)::ResponseResult<yb::master::CompactSysCatalogResponsePB>(yb::master::CompactSysCatalogResponsePB&&, std::__1::enable_if<HasMemberFunctionHasError<yb::master::CompactSysCatalogResponsePB>, void*>::type)
yb-admin_client.cc:yb::Result<yb::master::ChangeMasterClusterConfigResponsePB> yb::tools::(anonymous namespace)::ResponseResult<yb::master::ChangeMasterClusterConfigResponsePB>(yb::master::ChangeMasterClusterConfigResponsePB&&, std::__1::enable_if<HasMemberFunctionHasError<yb::master::ChangeMasterClusterConfigResponsePB>, void*>::type)
Line
Count
Source
189
20
    typename std::enable_if<HasMemberFunctionHasError<Response>, void*>::type = nullptr) {
190
  // Response has has_error method, use status from it
191
20
  if(response.has_error()) {
192
0
    return StatusFromPB(response.error().status());
193
0
  }
194
20
  return std::move(response);
195
20
}
yb-admin_client.cc:yb::Result<yb::master::IsInitDbDoneResponsePB> yb::tools::(anonymous namespace)::ResponseResult<yb::master::IsInitDbDoneResponsePB>(yb::master::IsInitDbDoneResponsePB&&, std::__1::enable_if<HasMemberFunctionHasError<yb::master::IsInitDbDoneResponsePB>, void*>::type)
Line
Count
Source
189
1
    typename std::enable_if<HasMemberFunctionHasError<Response>, void*>::type = nullptr) {
190
  // Response has has_error method, use status from it
191
1
  if(response.has_error()) {
192
0
    return StatusFromPB(response.error().status());
193
0
  }
194
1
  return std::move(response);
195
1
}
yb-admin_client.cc:yb::Result<yb::tserver::UpgradeYsqlResponsePB> yb::tools::(anonymous namespace)::ResponseResult<yb::tserver::UpgradeYsqlResponsePB>(yb::tserver::UpgradeYsqlResponsePB&&, std::__1::enable_if<HasMemberFunctionHasError<yb::tserver::UpgradeYsqlResponsePB>, void*>::type)
Line
Count
Source
189
1
    typename std::enable_if<HasMemberFunctionHasError<Response>, void*>::type = nullptr) {
190
  // Response has has_error method, use status from it
191
1
  if(response.has_error()) {
192
0
    return StatusFromPB(response.error().status());
193
0
  }
194
1
  return std::move(response);
195
1
}
yb-admin_client.cc:yb::Result<yb::master::GetMasterClusterConfigResponsePB> yb::tools::(anonymous namespace)::ResponseResult<yb::master::GetMasterClusterConfigResponsePB>(yb::master::GetMasterClusterConfigResponsePB&&, std::__1::enable_if<HasMemberFunctionHasError<yb::master::GetMasterClusterConfigResponsePB>, void*>::type)
Line
Count
Source
189
27
    typename std::enable_if<HasMemberFunctionHasError<Response>, void*>::type = nullptr) {
190
  // Response has has_error method, use status from it
191
27
  if(response.has_error()) {
192
0
    return StatusFromPB(response.error().status());
193
0
  }
194
27
  return std::move(response);
195
27
}
Unexecuted instantiation: yb-admin_client.cc:yb::Result<yb::master::SplitTabletResponsePB> yb::tools::(anonymous namespace)::ResponseResult<yb::master::SplitTabletResponsePB>(yb::master::SplitTabletResponsePB&&, std::__1::enable_if<HasMemberFunctionHasError<yb::master::SplitTabletResponsePB>, void*>::type)
Unexecuted instantiation: yb-admin_client.cc:yb::Result<yb::master::DisableTabletSplittingResponsePB> yb::tools::(anonymous namespace)::ResponseResult<yb::master::DisableTabletSplittingResponsePB>(yb::master::DisableTabletSplittingResponsePB&&, std::__1::enable_if<HasMemberFunctionHasError<yb::master::DisableTabletSplittingResponsePB>, void*>::type)
Unexecuted instantiation: yb-admin_client.cc:yb::Result<yb::master::IsTabletSplittingCompleteResponsePB> yb::tools::(anonymous namespace)::ResponseResult<yb::master::IsTabletSplittingCompleteResponsePB>(yb::master::IsTabletSplittingCompleteResponsePB&&, std::__1::enable_if<HasMemberFunctionHasError<yb::master::IsTabletSplittingCompleteResponsePB>, void*>::type)
196
197
template<class Response>
198
Result<Response> ResponseResult(Response&& response,
199
0
    typename std::enable_if<!HasMemberFunctionHasError<Response>, void*>::type = nullptr) {
200
  // Response has no has_error method, nothing to check
201
0
  return std::move(response);
202
0
}
Unexecuted instantiation: yb-admin_client.cc:yb::Result<yb::tserver::GetLogLocationResponsePB> yb::tools::(anonymous namespace)::ResponseResult<yb::tserver::GetLogLocationResponsePB>(yb::tserver::GetLogLocationResponsePB&&, std::__1::enable_if<!(HasMemberFunctionHasError<yb::tserver::GetLogLocationResponsePB>), void*>::type)
Unexecuted instantiation: yb-admin_client.cc:yb::Result<yb::tserver::ListTabletsForTabletServerResponsePB> yb::tools::(anonymous namespace)::ResponseResult<yb::tserver::ListTabletsForTabletServerResponsePB>(yb::tserver::ListTabletsForTabletServerResponsePB&&, std::__1::enable_if<!(HasMemberFunctionHasError<yb::tserver::ListTabletsForTabletServerResponsePB>), void*>::type)
203
204
5
const char* DatabasePrefix(YQLDatabase db) {
205
5
  switch(db) {
206
0
    case YQL_DATABASE_UNKNOWN: break;
207
5
    case YQL_DATABASE_CQL: return kDBTypePrefixCql;
208
0
    case YQL_DATABASE_PGSQL: return kDBTypePrefixYsql;
209
0
    case YQL_DATABASE_REDIS: return kDBTypePrefixRedis;
210
5
  }
211
0
  CHECK(false) << "Unexpected db type " << db;
212
0
  return kDBTypePrefixUnknown;
213
5
}
214
215
Result<TypedNamespaceName> ResolveNamespaceName(
216
    const Slice& prefix,
217
    const Slice& name,
218
23
    const YQLDatabase default_if_no_prefix = YQL_DATABASE_CQL) {
219
23
  auto db_type = YQL_DATABASE_UNKNOWN;
220
23
  if (!prefix.empty()) {
221
2
    static const std::array<pair<const char*, YQLDatabase>, 3> type_prefixes{
222
2
        make_pair(kDBTypePrefixCql, YQL_DATABASE_CQL),
223
2
        make_pair(kDBTypePrefixYsql, YQL_DATABASE_PGSQL),
224
2
        make_pair(kDBTypePrefixRedis, YQL_DATABASE_REDIS)};
225
4
    for (const auto& p : type_prefixes) {
226
4
      if (prefix == p.first) {
227
2
        db_type = p.second;
228
2
        break;
229
2
      }
230
4
    }
231
232
2
    if (db_type == YQL_DATABASE_UNKNOWN) {
233
0
      return STATUS_FORMAT(InvalidArgument, "Invalid db type name '$0'", prefix);
234
0
    }
235
21
  } else {
236
21
    db_type = (name == common::kRedisKeyspaceName ? 
YQL_DATABASE_REDIS1
:
default_if_no_prefix20
);
237
21
  }
238
23
  return TypedNamespaceName{.db_type = db_type, .name = name.cdata()};
239
23
}
240
241
3.34k
Slice GetTableIdAsSlice(const YBTableName& table_name) {
242
3.34k
  return table_name.table_id();
243
3.34k
}
244
245
60.3k
Slice GetNamespaceIdAsSlice(const YBTableName& table_name) {
246
60.3k
  return table_name.namespace_id();
247
60.3k
}
248
249
28.0k
Slice GetTableNameAsSlice(const YBTableName& table_name) {
250
28.0k
  return table_name.table_name();
251
28.0k
}
252
253
1
std::string FullNamespaceName(const master::NamespaceIdentifierPB& ns) {
254
1
  return Format("$0.$1", DatabasePrefix(ns.database_type()), ns.name());
255
1
}
256
257
struct NamespaceKey {
258
  explicit NamespaceKey(const master::NamespaceIdentifierPB& ns)
259
383
      : db_type(ns.database_type()), name(ns.name()) {
260
383
  }
261
262
  NamespaceKey(YQLDatabase d, const Slice& n)
263
23
      : db_type(d), name(n) {
264
23
  }
265
266
  YQLDatabase db_type;
267
  Slice name;
268
};
269
270
struct NamespaceComparator {
271
  using is_transparent = void;
272
273
  bool operator()(const master::NamespaceIdentifierPB& lhs,
274
155
                  const master::NamespaceIdentifierPB& rhs) const {
275
155
    return (*this)(NamespaceKey(lhs), NamespaceKey(rhs));
276
155
  }
277
278
50
  bool operator()(const master::NamespaceIdentifierPB& lhs, const NamespaceKey& rhs) const {
279
50
    return (*this)(NamespaceKey(lhs), rhs);
280
50
  }
281
282
23
  bool operator()(const NamespaceKey& lhs, const master::NamespaceIdentifierPB& rhs) const {
283
23
    return (*this)(lhs, NamespaceKey(rhs));
284
23
  }
285
286
228
  bool operator()(const NamespaceKey& lhs, const NamespaceKey& rhs) const {
287
228
    return lhs.db_type < rhs.db_type ||
288
228
           
(207
lhs.db_type == rhs.db_type207
&&
lhs.name.compare(rhs.name) < 0195
);
289
228
  }
290
};
291
292
struct DotStringParts {
293
  Slice prefix;
294
  Slice value;
295
};
296
297
35
DotStringParts SplitByDot(const std::string& str) {
298
35
  const size_t dot_pos = str.find('.');
299
35
  DotStringParts result{.prefix = Slice(), .value = str};
300
35
  if (dot_pos != string::npos) {
301
3
    result.prefix = Slice(str.data(), dot_pos);
302
3
    result.value.remove_prefix(dot_pos + 1);
303
3
  }
304
35
  return result;
305
35
}
306
307
}  // anonymous namespace
308
309
class TableNameResolver::Impl {
310
 public:
311
  struct TableIdTag;
312
  struct TableNameTag;
313
  using Values = std::vector<client::YBTableName>;
314
315
  Impl(std::vector<YBTableName> tables, vector<master::NamespaceIdentifierPB> namespaces)
316
19
      : current_namespace_(nullptr) {
317
19
    std::move(tables.begin(), tables.end(), std::inserter(tables_, tables_.end()));
318
19
    std::move(namespaces.begin(), namespaces.end(), std::inserter(namespaces_, namespaces_.end()));
319
19
  }
320
321
35
  Result<bool> Feed(const std::string& str) {
322
35
    const auto result = FeedImpl(str);
323
35
    if (!result.ok()) {
324
5
      current_namespace_ = nullptr;
325
5
    }
326
35
    return result;
327
35
  }
328
329
17
  Values& values() {
330
17
    return values_;
331
17
  }
332
333
8
  master::NamespaceIdentifierPB last_namespace() {
334
8
    if (!current_namespace_) {
335
0
      return master::NamespaceIdentifierPB();
336
0
    }
337
8
    return *current_namespace_;
338
8
  }
339
340
 private:
341
35
  Result<bool> FeedImpl(const std::string& str) {
342
35
    auto parts = SplitByDot(str);
343
35
    if (parts.prefix == kTableIDPrefix) {
344
1
      RETURN_NOT_OK(ProcessTableId(parts.value));
345
1
      return true;
346
34
    } else {
347
34
      if (!current_namespace_) {
348
23
        RETURN_NOT_OK(ProcessNamespace(parts.prefix, parts.value));
349
23
      } else {
350
11
        if (parts.prefix.empty()) {
351
11
          RETURN_NOT_OK(ProcessTableName(parts.value));
352
10
          return true;
353
11
        }
354
0
        return STATUS(InvalidArgument, "Wrong table name " + str);
355
11
      }
356
34
    }
357
19
    return false;
358
35
  }
359
360
23
  CHECKED_STATUS ProcessNamespace(const Slice& prefix, const Slice& value) {
361
23
    DCHECK(!current_namespace_);
362
23
    const auto ns = VERIFY_RESULT(ResolveNamespaceName(prefix, value));
363
0
    const auto i = namespaces_.find(NamespaceKey(ns.db_type, ns.name));
364
23
    if (i != namespaces_.end()) {
365
19
      current_namespace_ = &*i;
366
19
      return Status::OK();
367
19
    }
368
4
    return STATUS_FORMAT(
369
23
        InvalidArgument, "Namespace '$0' of type '$1' not found",
370
23
        ns.name, DatabasePrefix(ns.db_type));
371
23
  }
372
373
1
  CHECKED_STATUS ProcessTableId(const Slice& table_id) {
374
1
    const auto& idx = tables_.get<TableIdTag>();
375
1
    const auto i = idx.find(table_id);
376
1
    if (i == idx.end()) {
377
0
      return STATUS_FORMAT(InvalidArgument, "Table with id '$0' not found", table_id);
378
0
    }
379
1
    if (current_namespace_ && 
current_namespace_->id() != i->namespace_id()0
) {
380
0
      return STATUS_FORMAT(
381
0
          InvalidArgument, "Table with id '$0' belongs to different namespace '$1'",
382
0
          table_id, FullNamespaceName(*current_namespace_));
383
0
    }
384
1
    AppendTable(*i);
385
1
    return Status::OK();
386
1
  }
387
388
11
  CHECKED_STATUS ProcessTableName(const Slice& table_name) {
389
11
    DCHECK(current_namespace_);
390
11
    const auto& idx = tables_.get<TableNameTag>();
391
11
    const auto key = boost::make_tuple(Slice(current_namespace_->id()), table_name);
392
    // For some reason idx.equal_range(key) failed to compile.
393
11
    const auto range = std::make_pair(idx.lower_bound(key), idx.upper_bound(key));
394
11
    switch (std::distance(range.first, range.second)) {
395
1
      case 0:
396
1
        return STATUS_FORMAT(
397
0
            InvalidArgument, "Table with name '$0' not found in namespace '$1'",
398
0
            table_name, FullNamespaceName(*current_namespace_));
399
10
      case 1:
400
10
        AppendTable(*range.first);
401
10
        return Status::OK();
402
0
      default:
403
0
        return STATUS_FORMAT(
404
11
            InvalidArgument,
405
11
            "Namespace '$0' has multiple tables named '$1', specify table id instead",
406
11
            FullNamespaceName(*current_namespace_), table_name);
407
11
    }
408
11
  }
409
410
11
  void AppendTable(const YBTableName& table) {
411
11
    current_namespace_ = nullptr;
412
11
    values_.push_back(table);
413
11
  }
414
415
  using TableContainer = boost::multi_index_container<YBTableName,
416
      boost::multi_index::indexed_by<
417
          boost::multi_index::ordered_unique<
418
              boost::multi_index::tag<TableIdTag>,
419
              boost::multi_index::global_fun<const YBTableName&, Slice, &GetTableIdAsSlice>,
420
              Slice::Comparator
421
          >,
422
          boost::multi_index::ordered_non_unique<
423
              boost::multi_index::tag<TableNameTag>,
424
              boost::multi_index::composite_key<
425
                  YBTableName,
426
                  boost::multi_index::global_fun<const YBTableName&, Slice, &GetNamespaceIdAsSlice>,
427
                  boost::multi_index::global_fun<const YBTableName&, Slice, &GetTableNameAsSlice>
428
              >,
429
              boost::multi_index::composite_key_compare<
430
                  Slice::Comparator,
431
                  Slice::Comparator
432
              >
433
          >
434
      >
435
  >;
436
437
  TableContainer tables_;
438
  std::set<master::NamespaceIdentifierPB, NamespaceComparator> namespaces_;
439
  const master::NamespaceIdentifierPB* current_namespace_;
440
  Values values_;
441
};
442
443
TableNameResolver::TableNameResolver(std::vector<client::YBTableName> tables,
444
                                     std::vector<master::NamespaceIdentifierPB> namespaces)
445
19
    : impl_(new Impl(std::move(tables), std::move(namespaces))) {
446
19
}
447
448
38
TableNameResolver::TableNameResolver(TableNameResolver&&) = default;
449
450
57
TableNameResolver::~TableNameResolver() = default;
451
452
35
Result<bool> TableNameResolver::Feed(const std::string& value) {
453
35
  return impl_->Feed(value);
454
35
}
455
456
17
std::vector<client::YBTableName>& TableNameResolver::values() {
457
17
  return impl_->values();
458
17
}
459
460
8
master::NamespaceIdentifierPB TableNameResolver::last_namespace() {
461
8
  return impl_->last_namespace();
462
8
}
463
464
ClusterAdminClient::ClusterAdminClient(string addrs, MonoDelta timeout)
465
    : master_addr_list_(std::move(addrs)),
466
      timeout_(timeout),
467
112
      initted_(false) {}
468
469
ClusterAdminClient::ClusterAdminClient(const HostPort& init_master_addr, MonoDelta timeout)
470
    : init_master_addr_(init_master_addr),
471
      timeout_(timeout),
472
2
      initted_(false) {}
473
474
98
ClusterAdminClient::~ClusterAdminClient() {
475
98
  if (messenger_) {
476
98
    messenger_->Shutdown();
477
98
  }
478
98
}
479
480
Status ClusterAdminClient::DiscoverAllMasters(
481
    const HostPort& init_master_addr,
482
2
    std::string* all_master_addrs) {
483
484
2
  master::MasterClusterProxy proxy(proxy_cache_.get(), init_master_addr);
485
486
2
  VLOG(0) << "Initializing master leader list from single master at "
487
2
          << init_master_addr.ToString();
488
2
  const auto list_resp = VERIFY_RESULT(InvokeRpc(
489
2
      &master::MasterClusterProxy::ListMasters, proxy, ListMastersRequestPB()));
490
2
  if (list_resp.masters().empty()) {
491
0
    return  STATUS(NotFound, "no masters found");
492
0
  }
493
494
2
  std::vector<std::string> addrs;
495
6
  for (const auto& master : list_resp.masters()) {
496
6
    if (!master.has_registration()) {
497
0
      LOG(WARNING) << master.instance_id().permanent_uuid() << " has no registration.";
498
0
      continue;
499
0
    }
500
501
6
    if (master.registration().broadcast_addresses_size() > 0) {
502
0
      addrs.push_back(FormatFirstHostPort(master.registration().broadcast_addresses()));
503
6
    } else if (master.registration().private_rpc_addresses_size() > 0) {
504
6
      addrs.push_back(FormatFirstHostPort(master.registration().private_rpc_addresses()));
505
6
    } else {
506
0
      LOG(WARNING) << master.instance_id().permanent_uuid() << " has no rpc/broadcast address.";
507
0
      continue;
508
0
    }
509
6
  }
510
511
2
  if (addrs.empty()) {
512
0
    return STATUS(NotFound, "no masters found");
513
0
  }
514
515
2
  JoinStrings(addrs, ",", all_master_addrs);
516
2
  VLOG(0) << "Discovered full master list: " << *all_master_addrs;
517
2
  return Status::OK();
518
2
}
519
520
114
Status ClusterAdminClient::Init() {
521
114
  CHECK(!initted_);
522
523
  // Check if caller will initialize the client and related parts.
524
114
  rpc::MessengerBuilder messenger_builder("yb-admin");
525
114
  if (!FLAGS_certs_dir_name.empty()) {
526
1
    LOG(INFO) << "Built secure client using certs dir " << FLAGS_certs_dir_name;
527
1
    const auto& cert_name = FLAGS_client_node_name;
528
1
    secure_context_ = VERIFY_RESULT(server::CreateSecureContext(
529
0
        FLAGS_certs_dir_name, server::UseClientCerts(!cert_name.empty()), cert_name));
530
0
    server::ApplySecureContext(secure_context_.get(), &messenger_builder);
531
1
  }
532
533
114
  messenger_ = VERIFY_RESULT(messenger_builder.Build());
534
0
  proxy_cache_ = std::make_unique<rpc::ProxyCache>(messenger_.get());
535
536
114
  if (!init_master_addr_.host().empty()) {
537
2
    RETURN_NOT_OK(DiscoverAllMasters(init_master_addr_, &master_addr_list_));
538
2
  }
539
540
114
  yb_client_ = 
VERIFY_RESULT112
(112
YBClientBuilder()
541
0
      .add_master_server_addr(master_addr_list_)
542
0
      .default_admin_operation_timeout(timeout_)
543
0
      .wait_for_leader_election_on_init(FLAGS_wait_if_no_leader_master)
544
0
      .Build(messenger_.get()));
545
546
0
  ResetMasterProxy();
547
548
112
  initted_ = true;
549
112
  return Status::OK();
550
114
}
551
552
112
void ClusterAdminClient::ResetMasterProxy(const HostPort& leader_addr) {
553
  // Find the leader master's socket info to set up the master proxy.
554
112
  if (leader_addr.host().empty()) {
555
112
    leader_addr_ = yb_client_->GetMasterLeaderAddress();
556
112
  } else {
557
0
    leader_addr_ = leader_addr;
558
0
  }
559
560
112
  master_admin_proxy_ = std::make_unique<master::MasterAdminProxy>(
561
112
      proxy_cache_.get(), leader_addr_);
562
563
112
  master_backup_proxy_ = std::make_unique<master::MasterBackupProxy>(
564
112
      proxy_cache_.get(), leader_addr_);
565
566
112
  master_client_proxy_ = std::make_unique<master::MasterClientProxy>(
567
112
      proxy_cache_.get(), leader_addr_);
568
569
112
  master_cluster_proxy_ = std::make_unique<master::MasterClusterProxy>(
570
112
      proxy_cache_.get(), leader_addr_);
571
572
112
  master_ddl_proxy_ = std::make_unique<master::MasterDdlProxy>(
573
112
      proxy_cache_.get(), leader_addr_);
574
575
112
  master_encryption_proxy_ = std::make_unique<master::MasterEncryptionProxy>(
576
112
      proxy_cache_.get(), leader_addr_);
577
578
112
  master_replication_proxy_ = std::make_unique<master::MasterReplicationProxy>(
579
112
      proxy_cache_.get(), leader_addr_);
580
112
}
581
582
Status ClusterAdminClient::MasterLeaderStepDown(
583
    const string& leader_uuid,
584
2
    const string& new_leader_uuid) {
585
2
  auto master_proxy = std::make_unique<ConsensusServiceProxy>(proxy_cache_.get(), leader_addr_);
586
587
2
  return LeaderStepDown(leader_uuid, yb::master::kSysCatalogTabletId,
588
2
      new_leader_uuid, &master_proxy);
589
2
}
590
591
CHECKED_STATUS ClusterAdminClient::LeaderStepDownWithNewLeader(
592
    const std::string& tablet_id,
593
2
    const std::string& dest_ts_uuid) {
594
2
  return LeaderStepDown(
595
2
      /* leader_uuid */ std::string(),
596
2
      tablet_id,
597
2
      dest_ts_uuid,
598
2
      /* leader_proxy */ nullptr);
599
2
}
600
601
Status ClusterAdminClient::LeaderStepDown(
602
    const PeerId& leader_uuid,
603
    const TabletId& tablet_id,
604
    const PeerId& new_leader_uuid,
605
4
    std::unique_ptr<ConsensusServiceProxy>* leader_proxy) {
606
4
  LeaderStepDownRequestPB req;
607
4
  req.set_tablet_id(tablet_id);
608
4
  if (!new_leader_uuid.empty()) {
609
2
    req.set_new_leader_uuid(new_leader_uuid);
610
2
  } else {
611
2
    if (FLAGS_disable_graceful_transition) {
612
0
      req.set_disable_graceful_transition(true);
613
0
    }
614
2
  }
615
  // The API for InvokeRpcNoResponseCheck requires a raw pointer to a ConsensusServiceProxy, so
616
  // cache it outside, if we are creating a new proxy to a previously unknown leader.
617
4
  std::unique_ptr<ConsensusServiceProxy> new_proxy;
618
4
  if (!leader_uuid.empty()) {
619
    // TODO: validate leader_proxy ?
620
2
    req.set_dest_uuid(leader_uuid);
621
2
  } else {
622
    // Look up the location of the tablet leader from the Master.
623
2
    HostPort leader_addr;
624
2
    string lookup_leader_uuid;
625
2
    RETURN_NOT_OK(SetTabletPeerInfo(tablet_id, LEADER, &lookup_leader_uuid, &leader_addr));
626
2
    req.set_dest_uuid(lookup_leader_uuid);
627
2
    new_proxy = std::make_unique<ConsensusServiceProxy>(proxy_cache_.get(), leader_addr);
628
2
  }
629
4
  VLOG(2) << "Sending request " << req.DebugString() << " to node with uuid [" << leader_uuid
630
0
          << "]";
631
4
  const auto resp = VERIFY_RESULT(InvokeRpcNoResponseCheck(&ConsensusServiceProxy::LeaderStepDown,
632
4
      *(new_proxy ? new_proxy.get() : leader_proxy->get()),
633
4
      req));
634
4
  if (resp.has_error()) {
635
0
    LOG(ERROR) << "LeaderStepDown for " << leader_uuid << "received error "
636
0
      << resp.error().ShortDebugString();
637
0
    return StatusFromPB(resp.error().status());
638
0
  }
639
4
  return Status::OK();
640
4
}
641
642
// Force start an election on a randomly chosen non-leader peer of this tablet's raft quorum.
643
0
Status ClusterAdminClient::StartElection(const TabletId& tablet_id) {
644
0
  HostPort non_leader_addr;
645
0
  string non_leader_uuid;
646
0
  RETURN_NOT_OK(SetTabletPeerInfo(tablet_id, FOLLOWER, &non_leader_uuid, &non_leader_addr));
647
0
  ConsensusServiceProxy non_leader_proxy(proxy_cache_.get(), non_leader_addr);
648
0
  RunLeaderElectionRequestPB req;
649
0
  req.set_dest_uuid(non_leader_uuid);
650
0
  req.set_tablet_id(tablet_id);
651
0
  return ResultToStatus(InvokeRpc(
652
0
      &ConsensusServiceProxy::RunLeaderElection, non_leader_proxy, req));
653
0
}
654
655
// Look up the location of the tablet server leader or non-leader peer from the leader master
656
Status ClusterAdminClient::SetTabletPeerInfo(
657
    const TabletId& tablet_id,
658
    PeerMode mode,
659
    PeerId* peer_uuid,
660
2
    HostPort* peer_addr) {
661
2
  TSInfoPB peer_ts_info;
662
2
  RETURN_NOT_OK(GetTabletPeer(tablet_id, mode, &peer_ts_info));
663
2
  auto rpc_addresses = peer_ts_info.private_rpc_addresses();
664
2
  CHECK_GT(rpc_addresses.size(), 0) << peer_ts_info
665
0
        .ShortDebugString();
666
667
2
  *peer_addr = HostPortFromPB(rpc_addresses.Get(0));
668
2
  *peer_uuid = peer_ts_info.permanent_uuid();
669
2
  return Status::OK();
670
2
}
671
672
CHECKED_STATUS ClusterAdminClient::SetWalRetentionSecs(
673
  const YBTableName& table_name,
674
1
  const uint32_t wal_ret_secs) {
675
1
  auto alterer = yb_client_->NewTableAlterer(table_name);
676
1
  RETURN_NOT_OK(alterer->SetWalRetentionSecs(wal_ret_secs)->Alter());
677
1
  cout << "Set table " << table_name.table_name() << " WAL retention time to " << wal_ret_secs
678
1
       << " seconds." << endl;
679
1
  return Status::OK();
680
1
}
681
682
2
CHECKED_STATUS ClusterAdminClient::GetWalRetentionSecs(const YBTableName& table_name) {
683
2
  const auto info = VERIFY_RESULT(yb_client_->GetYBTableInfo(table_name));
684
2
  if (!info.wal_retention_secs) {
685
1
    cout << "WAL retention time not set for table " << table_name.table_name() << endl;
686
1
  } else {
687
1
    cout << "Found WAL retention time for table " << table_name.table_name() << ": "
688
1
         << info.wal_retention_secs.get() << " seconds" << endl;
689
1
  }
690
2
  return Status::OK();
691
2
}
692
693
Status ClusterAdminClient::ParseChangeType(
694
    const string& change_type,
695
3
    consensus::ChangeConfigType* cc_type) {
696
3
  consensus::ChangeConfigType cctype = consensus::UNKNOWN_CHANGE;
697
3
  *cc_type = cctype;
698
3
  string uppercase_change_type;
699
3
  ToUpperCase(change_type, &uppercase_change_type);
700
3
  if (!consensus::ChangeConfigType_Parse(uppercase_change_type, &cctype) ||
701
3
    cctype == consensus::UNKNOWN_CHANGE) {
702
0
    return STATUS(InvalidArgument, "Unsupported change_type", change_type);
703
0
  }
704
705
3
  *cc_type = cctype;
706
707
3
  return Status::OK();
708
3
}
709
710
Status ClusterAdminClient::ChangeConfig(
711
    const TabletId& tablet_id,
712
    const string& change_type,
713
    const PeerId& peer_uuid,
714
0
    const boost::optional<string>& member_type) {
715
0
  CHECK(initted_);
716
717
0
  consensus::ChangeConfigType cc_type;
718
0
  RETURN_NOT_OK(ParseChangeType(change_type, &cc_type));
719
720
0
  RaftPeerPB peer_pb;
721
0
  peer_pb.set_permanent_uuid(peer_uuid);
722
723
  // Parse the optional fields.
724
0
  if (member_type) {
725
0
    consensus::PeerMemberType member_type_val;
726
0
    string uppercase_member_type;
727
0
    ToUpperCase(*member_type, &uppercase_member_type);
728
0
    if (!PeerMemberType_Parse(uppercase_member_type, &member_type_val)) {
729
0
      return STATUS(InvalidArgument, "Unrecognized member_type", *member_type);
730
0
    }
731
0
    if (member_type_val != consensus::PeerMemberType::PRE_VOTER &&
732
0
        member_type_val != consensus::PeerMemberType::PRE_OBSERVER) {
733
0
      return STATUS(InvalidArgument, "member_type should be PRE_VOTER or PRE_OBSERVER");
734
0
    }
735
0
    peer_pb.set_member_type(member_type_val);
736
0
  }
737
738
  // Validate the existence of the optional fields.
739
0
  if (!member_type && cc_type == consensus::ADD_SERVER) {
740
0
    return STATUS(InvalidArgument, "Must specify member_type when adding a server.");
741
0
  }
742
743
  // Look up RPC address of peer if adding as a new server.
744
0
  if (cc_type == consensus::ADD_SERVER) {
745
0
    HostPort host_port = VERIFY_RESULT(GetFirstRpcAddressForTS(peer_uuid));
746
0
    HostPortToPB(host_port, peer_pb.mutable_last_known_private_addr()->Add());
747
0
  }
748
749
  // Look up the location of the tablet leader from the Master.
750
0
  HostPort leader_addr;
751
0
  string leader_uuid;
752
0
  RETURN_NOT_OK(SetTabletPeerInfo(tablet_id, LEADER, &leader_uuid, &leader_addr));
753
754
0
  auto consensus_proxy = std::make_unique<ConsensusServiceProxy>(proxy_cache_.get(), leader_addr);
755
  // If removing the leader ts, then first make it step down and that
756
  // starts an election and gets a new leader ts.
757
0
  if (cc_type == consensus::REMOVE_SERVER &&
758
0
      leader_uuid == peer_uuid) {
759
0
    string old_leader_uuid = leader_uuid;
760
0
    RETURN_NOT_OK(LeaderStepDown(
761
0
          leader_uuid, tablet_id, /* new_leader_uuid */ std::string(), &consensus_proxy));
762
0
    sleep(5);  // TODO - election completion timing is not known accurately
763
0
    RETURN_NOT_OK(SetTabletPeerInfo(tablet_id, LEADER, &leader_uuid, &leader_addr));
764
0
    if (leader_uuid == old_leader_uuid) {
765
0
      return STATUS(ConfigurationError,
766
0
                    "Old tablet server leader same as new even after re-election!");
767
0
    }
768
0
    consensus_proxy.reset(new ConsensusServiceProxy(proxy_cache_.get(), leader_addr));
769
0
  }
770
771
0
  consensus::ChangeConfigRequestPB req;
772
0
  req.set_dest_uuid(leader_uuid);
773
0
  req.set_tablet_id(tablet_id);
774
0
  req.set_type(cc_type);
775
0
  *req.mutable_server() = peer_pb;
776
0
  return ResultToStatus(InvokeRpc(
777
0
      &ConsensusServiceProxy::ChangeConfig, *consensus_proxy, req));
778
0
}
779
780
5
Result<std::string> ClusterAdminClient::GetMasterLeaderUuid() {
781
5
  std::string leader_uuid;
782
5
  const auto list_resp = VERIFY_RESULT_PREPEND(
783
5
      InvokeRpc(
784
5
          &master::MasterClusterProxy::ListMasters, *master_cluster_proxy_,
785
5
          ListMastersRequestPB()),
786
5
      "Could not locate master leader");
787
14
  for (const auto& master : list_resp.masters()) {
788
14
    if (master.role() == PeerRole::LEADER) {
789
5
      SCHECK(
790
5
          leader_uuid.empty(), ConfigurationError, "Found two LEADER's in the same raft config.");
791
5
      leader_uuid = master.instance_id().permanent_uuid();
792
5
    }
793
14
  }
794
5
  SCHECK(!leader_uuid.empty(), ConfigurationError, "Could not locate master leader!");
795
5
  return std::move(leader_uuid);
796
5
}
797
798
0
Status ClusterAdminClient::DumpMasterState(bool to_console) {
799
0
  CHECK(initted_);
800
0
  master::DumpMasterStateRequestPB req;
801
0
  req.set_peers_also(true);
802
0
  req.set_on_disk(true);
803
0
  req.set_return_dump_as_string(to_console);
804
805
0
  const auto resp = VERIFY_RESULT(InvokeRpc(
806
0
      &master::MasterClusterProxy::DumpState, *master_cluster_proxy_, req));
807
808
0
  if (to_console) {
809
0
    cout << resp.dump() << endl;
810
0
  } else {
811
0
    cout << "Master state dump has been completed and saved into "
812
0
            "the master respective log files." << endl;
813
0
  }
814
0
  return Status::OK();
815
0
}
816
817
0
Status ClusterAdminClient::GetLoadMoveCompletion() {
818
0
  CHECK(initted_);
819
0
  const auto resp = VERIFY_RESULT(InvokeRpc(
820
0
      &master::MasterClusterProxy::GetLoadMoveCompletion, *master_cluster_proxy_,
821
0
      master::GetLoadMovePercentRequestPB()));
822
0
  cout << "Percent complete = " << resp.percent() << " : "
823
0
    << resp.remaining() << " remaining out of " << resp.total() << endl;
824
0
  return Status::OK();
825
0
}
826
827
0
Status ClusterAdminClient::GetLeaderBlacklistCompletion() {
828
0
  CHECK(initted_);
829
0
  const auto resp = VERIFY_RESULT(InvokeRpc(
830
0
      &master::MasterClusterProxy::GetLeaderBlacklistCompletion, *master_cluster_proxy_,
831
0
      master::GetLeaderBlacklistPercentRequestPB()));
832
0
  cout << "Percent complete = " << resp.percent() << " : "
833
0
    << resp.remaining() << " remaining out of " << resp.total() << endl;
834
0
  return Status::OK();
835
0
}
836
837
0
Status ClusterAdminClient::GetIsLoadBalancerIdle() {
838
0
  CHECK(initted_);
839
840
0
  const bool is_idle = VERIFY_RESULT(yb_client_->IsLoadBalancerIdle());
841
0
  cout << "Idle = " << is_idle << endl;
842
0
  return Status::OK();
843
0
}
844
845
0
Status ClusterAdminClient::ListLeaderCounts(const YBTableName& table_name) {
846
0
  std::unordered_map<string, int> leader_counts = VERIFY_RESULT(GetLeaderCounts(table_name));
847
0
  int total_leader_count = 0;
848
0
  for (const auto& lc : leader_counts) { total_leader_count += lc.second; }
849
850
  // Calculate the standard deviation and adjusted deviation percentage according to the best and
851
  // worst-case scenarios. Best-case distribution is when leaders are evenly distributed and
852
  // worst-case is when leaders are all on one tablet server.
853
  // For example, say we have 16 leaders on 3 tablet servers:
854
  //   Leader distribution:    7 5 4
855
  //   Best-case scenario:     6 5 5
856
  //   Worst-case scenario:   12 0 0
857
  //   Standard deviation:    1.24722
858
  //   Adjusted deviation %:  10.9717%
859
0
  vector<double> leader_dist, best_case, worst_case;
860
0
  cout << RightPadToUuidWidth("Server UUID") << kColumnSep << "Leader Count" << endl;
861
0
  for (const auto& leader_count : leader_counts) {
862
0
    cout << leader_count.first << kColumnSep << leader_count.second << endl;
863
0
    leader_dist.push_back(leader_count.second);
864
0
  }
865
866
0
  if (!leader_dist.empty()) {
867
0
    for (size_t i = 0; i < leader_dist.size(); ++i) {
868
0
      best_case.push_back(total_leader_count / leader_dist.size());
869
0
      worst_case.push_back(0);
870
0
    }
871
0
    for (size_t i = 0; i < total_leader_count % leader_dist.size(); ++i) {
872
0
      ++best_case[i];
873
0
    }
874
0
    worst_case[0] = total_leader_count;
875
876
0
    double stdev = yb::standard_deviation(leader_dist);
877
0
    double best_stdev = yb::standard_deviation(best_case);
878
0
    double worst_stdev = yb::standard_deviation(worst_case);
879
0
    double percent_dev = (stdev - best_stdev) / (worst_stdev - best_stdev) * 100.0;
880
0
    cout << "Standard deviation: " << stdev << endl;
881
0
    cout << "Adjusted deviation percentage: " << percent_dev << "%" << endl;
882
0
  }
883
884
0
  return Status::OK();
885
0
}
886
887
Result<std::unordered_map<string, int>> ClusterAdminClient::GetLeaderCounts(
888
130
    const client::YBTableName& table_name) {
889
130
  vector<string> tablet_ids, ranges;
890
130
  RETURN_NOT_OK(yb_client_->GetTablets(table_name, 0, &tablet_ids, &ranges));
891
130
  master::GetTabletLocationsRequestPB req;
892
650
  for (const auto& tablet_id : tablet_ids) {
893
650
    req.add_tablet_ids(tablet_id);
894
650
  }
895
130
  const auto resp = VERIFY_RESULT(InvokeRpc(
896
130
      &master::MasterClientProxy::GetTabletLocations, *master_client_proxy_, req));
897
898
0
  std::unordered_map<string, int> leader_counts;
899
650
  for (const auto& locs : resp.tablet_locations()) {
900
1.95k
    for (const auto& replica : locs.replicas()) {
901
1.95k
      const auto uuid = replica.ts_info().permanent_uuid();
902
1.95k
      switch(replica.role()) {
903
650
        case PeerRole::LEADER:
904
          // If this is a leader, increment leader counts.
905
650
          ++leader_counts[uuid];
906
650
          break;
907
1.30k
        case PeerRole::FOLLOWER:
908
          // If this is a follower, touch the leader count entry also so that tablet server with
909
          // followers only and 0 leader will be accounted for still.
910
1.30k
          leader_counts[uuid];
911
1.30k
          break;
912
0
        default:
913
0
          break;
914
1.95k
      }
915
1.95k
    }
916
650
  }
917
918
130
  return leader_counts;
919
130
}
920
921
1
Status ClusterAdminClient::SetupRedisTable() {
922
1
  const YBTableName table_name(
923
1
      YQL_DATABASE_REDIS, common::kRedisKeyspaceName, common::kRedisTableName);
924
1
  RETURN_NOT_OK(yb_client_->CreateNamespaceIfNotExists(common::kRedisKeyspaceName,
925
1
                                                       YQLDatabase::YQL_DATABASE_REDIS));
926
  // Try to create the table.
927
1
  std::unique_ptr<yb::client::YBTableCreator> table_creator(yb_client_->NewTableCreator());
928
1
  Status s = table_creator->table_name(table_name)
929
1
                              .table_type(yb::client::YBTableType::REDIS_TABLE_TYPE)
930
1
                              .Create();
931
  // If we could create it, then all good!
932
1
  if (s.ok()) {
933
1
    LOG(INFO) << "Table '" << table_name.ToString() << "' created.";
934
    // If the table was already there, also not an error...
935
1
  } else 
if (0
s.IsAlreadyPresent()0
) {
936
0
    LOG(INFO) << "Table '" << table_name.ToString() << "' already exists";
937
0
  } else {
938
    // If any other error, report that!
939
0
    LOG(ERROR) << s;
940
0
    RETURN_NOT_OK(s);
941
0
  }
942
1
  return Status::OK();
943
1
}
944
945
0
Status ClusterAdminClient::DropRedisTable() {
946
0
  const YBTableName table_name(
947
0
      YQL_DATABASE_REDIS, common::kRedisKeyspaceName, common::kRedisTableName);
948
0
  Status s = yb_client_->DeleteTable(table_name, true /* wait */);
949
0
  if (s.ok()) {
950
0
    LOG(INFO) << "Table '" << table_name.ToString() << "' deleted.";
951
0
  } else if (s.IsNotFound()) {
952
0
    LOG(INFO) << "Table '" << table_name.ToString() << "' does not exist.";
953
0
  } else {
954
0
    RETURN_NOT_OK(s);
955
0
  }
956
0
  return Status::OK();
957
0
}
958
959
Status ClusterAdminClient::ChangeMasterConfig(
960
    const string& change_type,
961
    const string& peer_host,
962
    uint16_t peer_port,
963
3
    const string& given_uuid) {
964
3
  CHECK(initted_);
965
966
3
  consensus::ChangeConfigType cc_type;
967
3
  RETURN_NOT_OK(ParseChangeType(change_type, &cc_type));
968
969
3
  string peer_uuid;
970
3
  if (cc_type == consensus::ADD_SERVER) {
971
1
    VLOG(1) << "ChangeMasterConfig: attempt to get UUID for changed host: " << peer_host << ":"
972
0
            << peer_port;
973
1
    RETURN_NOT_OK(yb_client_->GetMasterUUID(peer_host, peer_port, &peer_uuid));
974
1
    if (!given_uuid.empty() && 
given_uuid != peer_uuid0
) {
975
0
      return STATUS_FORMAT(
976
0
          InvalidArgument, "Specified uuid $0. But the server has uuid $1", given_uuid, peer_uuid);
977
0
    }
978
2
  } else {
979
    // Do not verify uuid for REMOVE_SERVER, as the server may not be accessible.
980
2
    peer_uuid = given_uuid;
981
2
  }
982
3
  VLOG(1) << "ChangeMasterConfig: " << change_type << " | " << peer_host << ":" << peer_port
983
0
          << " uuid : " << peer_uuid;
984
985
3
  auto leader_uuid = VERIFY_RESULT(GetMasterLeaderUuid());
986
987
  // If removing the leader master, then first make it step down and that
988
  // starts an election and gets a new leader master.
989
0
  const HostPort changed_master_addr(peer_host, peer_port);
990
3
  if (cc_type == consensus::REMOVE_SERVER && 
leader_addr_ == changed_master_addr2
) {
991
0
    VLOG(1) << "ChangeMasterConfig: request leader " << leader_addr_
992
0
            << " to step down before removal.";
993
0
    string old_leader_uuid = leader_uuid;
994
0
    RETURN_NOT_OK(MasterLeaderStepDown(leader_uuid));
995
0
    sleep(5);  // TODO - wait for exactly the time needed for new leader to get elected.
996
    // Reget the leader master's socket info to set up the proxy
997
0
    ResetMasterProxy(VERIFY_RESULT(yb_client_->RefreshMasterLeaderAddress()));
998
0
    leader_uuid = VERIFY_RESULT(GetMasterLeaderUuid());
999
0
    if (leader_uuid == old_leader_uuid) {
1000
0
      return STATUS(ConfigurationError,
1001
0
        Substitute("Old master leader uuid $0 same as new one even after stepdown!", leader_uuid));
1002
0
    }
1003
    // Go ahead below and send the actual config change message to the new master
1004
0
  }
1005
1006
3
  std::unique_ptr<consensus::ConsensusServiceProxy> leader_proxy(
1007
3
    new consensus::ConsensusServiceProxy(proxy_cache_.get(), leader_addr_));
1008
3
  consensus::ChangeConfigRequestPB req;
1009
1010
3
  RaftPeerPB peer_pb;
1011
3
  if (!peer_uuid.empty()) {
1012
2
    peer_pb.set_permanent_uuid(peer_uuid);
1013
2
  }
1014
1015
3
  if (cc_type == consensus::ADD_SERVER) {
1016
1
    peer_pb.set_member_type(consensus::PeerMemberType::PRE_VOTER);
1017
2
  } else {  // REMOVE_SERVER
1018
2
    req.set_use_host(peer_uuid.empty());
1019
2
  }
1020
3
  HostPortPB *peer_host_port = peer_pb.mutable_last_known_private_addr()->Add();
1021
3
  peer_host_port->set_port(peer_port);
1022
3
  peer_host_port->set_host(peer_host);
1023
3
  req.set_dest_uuid(leader_uuid);
1024
3
  req.set_tablet_id(yb::master::kSysCatalogTabletId);
1025
3
  req.set_type(cc_type);
1026
3
  *req.mutable_server() = peer_pb;
1027
1028
3
  VLOG(1) << "ChangeMasterConfig: ChangeConfig for tablet id " << yb::master::kSysCatalogTabletId
1029
0
          << " to host " << leader_addr_;
1030
3
  RETURN_NOT_OK(InvokeRpc(&consensus::ConsensusServiceProxy::ChangeConfig, *leader_proxy, req));
1031
1032
3
  VLOG
(1) << "ChangeMasterConfig: update yb client to reflect config change."0
;
1033
3
  if (cc_type == consensus::ADD_SERVER) {
1034
1
    RETURN_NOT_OK(yb_client_->AddMasterToClient(changed_master_addr));
1035
2
  } else {
1036
2
    RETURN_NOT_OK(yb_client_->RemoveMasterFromClient(changed_master_addr));
1037
2
  }
1038
1039
3
  return Status::OK();
1040
3
}
1041
1042
Status ClusterAdminClient::GetTabletLocations(const TabletId& tablet_id,
1043
2
                                              TabletLocationsPB* locations) {
1044
2
  master::GetTabletLocationsRequestPB req;
1045
2
  req.add_tablet_ids(tablet_id);
1046
2
  const auto resp = VERIFY_RESULT(InvokeRpc(
1047
2
      &master::MasterClientProxy::GetTabletLocations, *master_client_proxy_, req));
1048
1049
2
  if (resp.errors_size() > 0) {
1050
    // This tool only needs to support one-by-one requests for tablet
1051
    // locations, so we only look at the first error.
1052
0
    return StatusFromPB(resp.errors(0).status());
1053
0
  }
1054
1055
  // Same as above, no batching, and we already got past the error checks.
1056
2
  CHECK_EQ
(1, resp.tablet_locations_size()) << resp.ShortDebugString()0
;
1057
1058
2
  *locations = resp.tablet_locations(0);
1059
2
  return Status::OK();
1060
2
}
1061
1062
Status ClusterAdminClient::GetTabletPeer(const TabletId& tablet_id,
1063
                                         PeerMode mode,
1064
2
                                         TSInfoPB* ts_info) {
1065
2
  TabletLocationsPB locations;
1066
2
  RETURN_NOT_OK(GetTabletLocations(tablet_id, &locations));
1067
2
  CHECK_EQ
(tablet_id, locations.tablet_id()) << locations.ShortDebugString()0
;
1068
2
  bool found = false;
1069
2
  for (const TabletLocationsPB::ReplicaPB& replica : locations.replicas()) {
1070
2
    if (mode == LEADER && replica.role() == PeerRole::LEADER) {
1071
2
      *ts_info = replica.ts_info();
1072
2
      found = true;
1073
2
      break;
1074
2
    }
1075
0
    if (mode == FOLLOWER && replica.role() != PeerRole::LEADER) {
1076
0
      *ts_info = replica.ts_info();
1077
0
      found = true;
1078
0
      break;
1079
0
    }
1080
0
  }
1081
1082
2
  if (!found) {
1083
0
    return STATUS(NotFound,
1084
0
      Substitute("No peer replica found in $0 mode for tablet $1", mode, tablet_id));
1085
0
  }
1086
1087
2
  return Status::OK();
1088
2
}
1089
1090
Status ClusterAdminClient::ListTabletServers(
1091
1
    RepeatedPtrField<ListTabletServersResponsePB::Entry>* servers) {
1092
1
  auto resp = VERIFY_RESULT(InvokeRpc(
1093
1
      &master::MasterClusterProxy::ListTabletServers, *master_cluster_proxy_,
1094
1
      ListTabletServersRequestPB()));
1095
0
  *servers = std::move(*resp.mutable_servers());
1096
1
  return Status::OK();
1097
1
}
1098
1099
0
Result<HostPort> ClusterAdminClient::GetFirstRpcAddressForTS(const PeerId& uuid) {
1100
0
  RepeatedPtrField<ListTabletServersResponsePB::Entry> servers;
1101
0
  RETURN_NOT_OK(ListTabletServers(&servers));
1102
0
  for (const ListTabletServersResponsePB::Entry& server : servers) {
1103
0
    if (server.instance_id().permanent_uuid() == uuid) {
1104
0
      if (!server.has_registration() ||
1105
0
          server.registration().common().private_rpc_addresses().empty()) {
1106
0
        break;
1107
0
      }
1108
0
      return HostPortFromPB(server.registration().common().private_rpc_addresses(0));
1109
0
    }
1110
0
  }
1111
1112
0
  return STATUS_FORMAT(
1113
0
      NotFound, "Server with UUID $0 has no RPC address registered with the Master", uuid);
1114
0
}
1115
1116
0
Status ClusterAdminClient::ListAllTabletServers(bool exclude_dead) {
1117
0
  RepeatedPtrField<ListTabletServersResponsePB::Entry> servers;
1118
0
  RETURN_NOT_OK(ListTabletServers(&servers));
1119
0
  char kSpaceSep = ' ';
1120
1121
0
  cout << RightPadToUuidWidth("Tablet Server UUID") << kSpaceSep
1122
0
        << kRpcHostPortHeading << kSpaceSep
1123
0
        << RightPadToWidth("Heartbeat delay", kLongColWidth) << kSpaceSep
1124
0
        << RightPadToWidth("Status", kSmallColWidth) << kSpaceSep
1125
0
        << RightPadToWidth("Reads/s", kSmallColWidth) << kSpaceSep
1126
0
        << RightPadToWidth("Writes/s", kSmallColWidth) << kSpaceSep
1127
0
        << RightPadToWidth("Uptime", kSmallColWidth) << kSpaceSep
1128
0
        << RightPadToWidth("SST total size", kLongColWidth) << kSpaceSep
1129
0
        << RightPadToWidth("SST uncomp size", kLongColWidth) << kSpaceSep
1130
0
        << RightPadToWidth("SST #files", kLongColWidth) << kSpaceSep
1131
0
        << RightPadToWidth("Memory", kSmallColWidth) << kSpaceSep
1132
0
        << endl;
1133
0
  for (const ListTabletServersResponsePB::Entry& server : servers) {
1134
0
    if (exclude_dead && server.has_alive() && !server.alive()) {
1135
0
      continue;
1136
0
    }
1137
0
    std::stringstream time_str;
1138
0
    auto heartbeat_delay_ms = server.has_millis_since_heartbeat() ?
1139
0
                               server.millis_since_heartbeat() : 0;
1140
0
    time_str << std::fixed << std::setprecision(2) << (heartbeat_delay_ms/1000.0) << "s";
1141
0
    auto status_str = server.has_alive() ? (server.alive() ? "ALIVE" : "DEAD") : "UNKNOWN";
1142
0
    cout << server.instance_id().permanent_uuid() << kSpaceSep
1143
0
         << FormatFirstHostPort(server.registration().common().private_rpc_addresses())
1144
0
         << kSpaceSep
1145
0
         << RightPadToWidth(time_str.str(), kLongColWidth) << kSpaceSep
1146
0
         << RightPadToWidth(status_str, kSmallColWidth) << kSpaceSep
1147
0
         << RightPadToWidth(FormatDouble(server.metrics().read_ops_per_sec()), kSmallColWidth)
1148
0
         << kSpaceSep
1149
0
         << RightPadToWidth(FormatDouble(server.metrics().write_ops_per_sec()), kSmallColWidth)
1150
0
         << kSpaceSep
1151
0
         << RightPadToWidth(server.metrics().uptime_seconds(), kSmallColWidth) << kSpaceSep
1152
0
         << RightPadToWidth(HumanizeBytes(server.metrics().total_sst_file_size()), kLongColWidth)
1153
0
         << kSpaceSep
1154
0
         << RightPadToWidth(HumanizeBytes(server.metrics().uncompressed_sst_file_size()),
1155
0
                            kLongColWidth)
1156
0
         << kSpaceSep
1157
0
         << RightPadToWidth(server.metrics().num_sst_files(), kLongColWidth) << kSpaceSep
1158
0
         << RightPadToWidth(HumanizeBytes(server.metrics().total_ram_usage()), kSmallColWidth)
1159
0
         << kSpaceSep
1160
0
         << endl;
1161
0
  }
1162
1163
0
  return Status::OK();
1164
0
}
1165
1166
11
Status ClusterAdminClient::ListAllMasters() {
1167
11
  const auto lresp = VERIFY_RESULT(InvokeRpc(
1168
11
      &master::MasterClusterProxy::ListMasters, *master_cluster_proxy_,
1169
11
      ListMastersRequestPB()));
1170
1171
11
  if (lresp.has_error()) {
1172
0
    LOG(ERROR) << "Error: querying leader master for live master info : "
1173
0
               << lresp.error().DebugString() << endl;
1174
0
    return STATUS(RemoteError, lresp.error().DebugString());
1175
0
  }
1176
1177
11
  cout << RightPadToUuidWidth("Master UUID") << kColumnSep
1178
11
        << RightPadToWidth(kRpcHostPortHeading, kHostPortColWidth) << kColumnSep
1179
11
        << RightPadToWidth("State", kSmallColWidth) << kColumnSep
1180
11
        << "Role" << endl;
1181
1182
30
  for (const auto& master : lresp.masters()) {
1183
30
      const auto master_reg = master.has_registration() ? &master.registration() : 
nullptr0
;
1184
30
      cout << (master.has_instance_id() ? master.instance_id().permanent_uuid()
1185
30
                          : 
RightPadToUuidWidth("UNKNOWN_UUID")0
) << kColumnSep;
1186
30
      cout << RightPadToWidth(
1187
30
                master_reg ? FormatFirstHostPort(master_reg->private_rpc_addresses())
1188
30
                            : 
"UNKNOWN"0
, kHostPortColWidth)
1189
30
            << kColumnSep;
1190
30
      cout << RightPadToWidth((master.has_error() ?
1191
28
                                
PBEnumToString(master.error().code())2
: "ALIVE"),
1192
30
                              kSmallColWidth)
1193
30
            << kColumnSep;
1194
30
      cout << (master.has_role() ? 
PBEnumToString(master.role())28
:
"UNKNOWN"2
) << endl;
1195
30
  }
1196
1197
11
  return Status::OK();
1198
11
}
1199
1200
0
Status ClusterAdminClient::ListTabletServersLogLocations() {
1201
0
  RepeatedPtrField<ListTabletServersResponsePB::Entry> servers;
1202
0
  RETURN_NOT_OK(ListTabletServers(&servers));
1203
1204
0
  if (!servers.empty()) {
1205
0
    cout << RightPadToUuidWidth("TS UUID") << kColumnSep
1206
0
         << kRpcHostPortHeading << kColumnSep
1207
0
         << "LogLocation"
1208
0
         << endl;
1209
0
  }
1210
1211
0
  for (const ListTabletServersResponsePB::Entry& server : servers) {
1212
0
    auto ts_uuid = server.instance_id().permanent_uuid();
1213
1214
0
    HostPort ts_addr = VERIFY_RESULT(GetFirstRpcAddressForTS(ts_uuid));
1215
1216
0
    TabletServerServiceProxy ts_proxy(proxy_cache_.get(), ts_addr);
1217
1218
0
    const auto resp = VERIFY_RESULT(InvokeRpc(
1219
0
        &TabletServerServiceProxy::GetLogLocation, ts_proxy, tserver::GetLogLocationRequestPB()));
1220
0
    cout << ts_uuid << kColumnSep
1221
0
         << ts_addr << kColumnSep
1222
0
         << resp.log_location() << endl;
1223
0
  }
1224
1225
0
  return Status::OK();
1226
0
}
1227
1228
Status ClusterAdminClient::ListTables(bool include_db_type,
1229
                                      bool include_table_id,
1230
1
                                      bool include_table_type) {
1231
1
  const auto tables = VERIFY_RESULT(yb_client_->ListTables());
1232
1
  const auto& namespace_metadata = VERIFY_RESULT_REF(GetNamespaceMap());
1233
0
  vector<string> names;
1234
17
  for (const auto& table : tables) {
1235
17
    std::stringstream str;
1236
17
    if (include_db_type) {
1237
0
      const auto db_type_iter = namespace_metadata.find(table.namespace_id());
1238
0
      if (db_type_iter != namespace_metadata.end()) {
1239
0
        str << DatabasePrefix(db_type_iter->second.database_type()) << '.';
1240
0
      } else {
1241
0
        LOG(WARNING) << "Table in unknown namespace found " << table.ToString();
1242
0
        continue;
1243
0
      }
1244
0
    }
1245
17
    str << table.ToString();
1246
17
    if (include_table_id) {
1247
0
      str << ' ' << table.table_id();
1248
0
    }
1249
17
    if (include_table_type) {
1250
0
      boost::optional<master::RelationType> relation_type = table.relation_type();
1251
0
      switch (relation_type.get()) {
1252
0
        case master::SYSTEM_TABLE_RELATION:
1253
0
          str << " catalog";
1254
0
          break;
1255
0
        case master::USER_TABLE_RELATION:
1256
0
          str << " table";
1257
0
          break;
1258
0
        case master::INDEX_TABLE_RELATION:
1259
0
          str << " index";
1260
0
          break;
1261
0
        default:
1262
0
          str << " other";
1263
0
      }
1264
0
    }
1265
17
    names.push_back(str.str());
1266
17
  }
1267
1
  sort(names.begin(), names.end());
1268
1
  copy(names.begin(), names.end(), std::ostream_iterator<string>(cout, "\n"));
1269
1
  return Status::OK();
1270
1
}
1271
1272
struct FollowerDetails {
1273
  string uuid;
1274
  string host_port;
1275
2
  FollowerDetails(const string &u, const string &hp) : uuid(u), host_port(hp) {}
1276
};
1277
1278
Status ClusterAdminClient::ListTablets(
1279
3
    const YBTableName& table_name, int max_tablets, bool json, bool followers) {
1280
3
  vector<string> tablet_uuids, ranges;
1281
3
  std::vector<master::TabletLocationsPB> locations;
1282
3
  RETURN_NOT_OK(yb_client_->GetTablets(
1283
3
      table_name, max_tablets, &tablet_uuids, &ranges, &locations));
1284
1285
3
  rapidjson::Document document(rapidjson::kObjectType);
1286
3
  rapidjson::Value json_tablets(rapidjson::kArrayType);
1287
3
  CHECK(json_tablets.IsArray());
1288
1289
3
  if (!json) {
1290
2
    cout << RightPadToUuidWidth("Tablet-UUID") << kColumnSep
1291
2
         << RightPadToWidth("Range", kPartitionRangeColWidth) << kColumnSep
1292
2
         << RightPadToWidth("Leader-IP", kLongColWidth) << kColumnSep << "Leader-UUID";
1293
2
    if (followers) {
1294
1
      cout << kColumnSep << "Followers";
1295
1
    }
1296
2
    cout << endl;
1297
2
  }
1298
1299
6
  for (size_t i = 0; i < tablet_uuids.size(); 
i++3
) {
1300
3
    const string& tablet_uuid = tablet_uuids[i];
1301
3
    string leader_host_port;
1302
3
    string leader_uuid;
1303
3
    string follower_host_port;
1304
3
    vector<FollowerDetails> follower_list;
1305
3
    string follower_list_str;
1306
3
    const auto& locations_of_this_tablet = locations[i];
1307
9
    for (const auto& replica : locations_of_this_tablet.replicas()) {
1308
9
      if (replica.role() == PeerRole::LEADER) {
1309
3
        if (leader_host_port.empty()) {
1310
3
          leader_host_port = HostPortPBToString(replica.ts_info().private_rpc_addresses(0));
1311
3
          leader_uuid = replica.ts_info().permanent_uuid();
1312
3
        } else {
1313
0
          LOG(ERROR) << "Multiple leader replicas found for tablet " << tablet_uuid
1314
0
                     << ": " << locations_of_this_tablet.ShortDebugString();
1315
0
        }
1316
6
      } else {
1317
6
        if (followers) {
1318
4
          string follower_host_port =
1319
4
            HostPortPBToString(replica.ts_info().private_rpc_addresses(0));
1320
4
          if (json) {
1321
2
            follower_list.push_back(
1322
2
                FollowerDetails(replica.ts_info().permanent_uuid(), follower_host_port));
1323
2
          } else {
1324
2
            if (!follower_list_str.empty()) {
1325
1
              follower_list_str += ",";
1326
1
            }
1327
2
            follower_list_str += follower_host_port;
1328
2
          }
1329
4
        }
1330
6
      }
1331
9
    }
1332
1333
3
    if (json) {
1334
1
      rapidjson::Value json_tablet(rapidjson::kObjectType);
1335
1
      AddStringField("id", tablet_uuid, &json_tablet, &document.GetAllocator());
1336
1
      const auto& partition = locations_of_this_tablet.partition();
1337
1
      AddStringField("partition_key_start",
1338
1
                     Slice(partition.partition_key_start()).ToDebugHexString(), &json_tablet,
1339
1
                     &document.GetAllocator());
1340
1
      AddStringField("partition_key_end",
1341
1
                     Slice(partition.partition_key_end()).ToDebugHexString(), &json_tablet,
1342
1
                     &document.GetAllocator());
1343
1
      rapidjson::Value json_leader(rapidjson::kObjectType);
1344
1
      AddStringField("uuid", leader_uuid, &json_leader, &document.GetAllocator());
1345
1
      AddStringField("endpoint", leader_host_port, &json_leader, &document.GetAllocator());
1346
1
      json_tablet.AddMember(rapidjson::StringRef("leader"), json_leader, document.GetAllocator());
1347
1
      if (followers) {
1348
1
        rapidjson::Value json_followers(rapidjson::kArrayType);
1349
1
        CHECK(json_followers.IsArray());
1350
2
        for (const FollowerDetails &follower : follower_list) {
1351
2
          rapidjson::Value json_follower(rapidjson::kObjectType);
1352
2
          AddStringField("uuid", follower.uuid, &json_follower, &document.GetAllocator());
1353
2
          AddStringField("endpoint", follower.host_port, &json_follower, &document.GetAllocator());
1354
2
          json_followers.PushBack(json_follower, document.GetAllocator());
1355
2
        }
1356
1
        json_tablet.AddMember(rapidjson::StringRef("followers"), json_followers,
1357
1
                              document.GetAllocator());
1358
1
      }
1359
1
      json_tablets.PushBack(json_tablet, document.GetAllocator());
1360
2
    } else {
1361
2
      cout << tablet_uuid << kColumnSep << RightPadToWidth(ranges[i], kPartitionRangeColWidth)
1362
2
           << kColumnSep << RightPadToWidth(leader_host_port, kLongColWidth) << kColumnSep
1363
2
           << leader_uuid;
1364
2
      if (followers) {
1365
1
        cout << kColumnSep << follower_list_str;
1366
1
      }
1367
2
      cout << endl;
1368
2
    }
1369
3
  }
1370
1371
3
  if (json) {
1372
1
    document.AddMember("tablets", json_tablets, document.GetAllocator());
1373
1
    std::cout << common::PrettyWriteRapidJsonToString(document) << std::endl;
1374
1
  }
1375
1376
3
  return Status::OK();
1377
3
}
1378
1379
1
Status ClusterAdminClient::LaunchBackfillIndexForTable(const YBTableName& table_name) {
1380
1
  master::LaunchBackfillIndexForTableRequestPB req;
1381
1
  table_name.SetIntoTableIdentifierPB(req.mutable_table_identifier());
1382
1
  const auto resp = VERIFY_RESULT(InvokeRpc(
1383
1
      &master::MasterDdlProxy::LaunchBackfillIndexForTable, *master_ddl_proxy_, req));
1384
1
  if (resp.has_error()) {
1385
0
    return STATUS(RemoteError, resp.error().DebugString());
1386
0
  }
1387
1
  return Status::OK();
1388
1
}
1389
1390
2
Status ClusterAdminClient::ListPerTabletTabletServers(const TabletId& tablet_id) {
1391
2
  master::GetTabletLocationsRequestPB req;
1392
2
  req.add_tablet_ids(tablet_id);
1393
2
  const auto resp = VERIFY_RESULT(InvokeRpc(
1394
2
      &master::MasterClientProxy::GetTabletLocations, *master_client_proxy_, req));
1395
1396
2
  if (resp.tablet_locations_size() != 1) {
1397
0
    if (resp.tablet_locations_size() > 0) {
1398
0
      std::cerr << "List of all incorrect locations - " << resp.tablet_locations_size()
1399
0
                << " : " << endl;
1400
0
      const auto limit = std::min(resp.tablet_locations_size(), MAX_NUM_ELEMENTS_TO_SHOW_ON_ERROR);
1401
0
      for (int i = 0; i < limit; ++i) {
1402
0
        std::cerr << i << " : " << resp.tablet_locations(i).DebugString();
1403
0
      }
1404
0
      std::cerr << endl;
1405
0
    }
1406
0
    return STATUS_FORMAT(IllegalState,
1407
0
                         "Incorrect number of locations $0 for tablet $1.",
1408
0
                         resp.tablet_locations_size(), tablet_id);
1409
0
  }
1410
1411
2
  TabletLocationsPB locs = resp.tablet_locations(0);
1412
2
  if (!locs.replicas().empty()) {
1413
2
    cout << RightPadToUuidWidth("Server UUID") << kColumnSep
1414
2
         << RightPadToWidth(kRpcHostPortHeading, kHostPortColWidth) << kColumnSep
1415
2
         << "Role" << endl;
1416
2
  }
1417
6
  for (const auto& replica : locs.replicas()) {
1418
6
    cout << replica.ts_info().permanent_uuid() << kColumnSep
1419
6
         << RightPadToWidth(HostPortPBToString(replica.ts_info().private_rpc_addresses(0)),
1420
6
                            kHostPortColWidth) << kColumnSep
1421
6
         << PBEnumToString(replica.role()) << endl;
1422
6
  }
1423
1424
2
  return Status::OK();
1425
2
}
1426
1427
0
Status ClusterAdminClient::DeleteTable(const YBTableName& table_name) {
1428
0
  RETURN_NOT_OK(yb_client_->DeleteTable(table_name));
1429
0
  cout << "Deleted table " << table_name.ToString() << endl;
1430
0
  return Status::OK();
1431
0
}
1432
1433
0
Status ClusterAdminClient::DeleteTableById(const TableId& table_id) {
1434
0
  RETURN_NOT_OK(yb_client_->DeleteTable(table_id));
1435
0
  cout << "Deleted table " << table_id << endl;
1436
0
  return Status::OK();
1437
0
}
1438
1439
0
Status ClusterAdminClient::DeleteIndex(const YBTableName& table_name) {
1440
0
  YBTableName indexed_table_name;
1441
0
  RETURN_NOT_OK(yb_client_->DeleteIndexTable(table_name, &indexed_table_name));
1442
0
  cout << "Deleted index " << table_name.ToString() << " from table " <<
1443
0
      indexed_table_name.ToString() << endl;
1444
0
  return Status::OK();
1445
0
}
1446
1447
0
Status ClusterAdminClient::DeleteIndexById(const TableId& table_id) {
1448
0
  YBTableName indexed_table_name;
1449
0
  RETURN_NOT_OK(yb_client_->DeleteIndexTable(table_id, &indexed_table_name));
1450
0
  cout << "Deleted index " << table_id << " from table " <<
1451
0
      indexed_table_name.ToString() << endl;
1452
0
  return Status::OK();
1453
0
}
1454
1455
0
Status ClusterAdminClient::DeleteNamespace(const TypedNamespaceName& namespace_name) {
1456
0
  RETURN_NOT_OK(yb_client_->DeleteNamespace(namespace_name.name, namespace_name.db_type));
1457
0
  cout << "Deleted namespace " << namespace_name.name << endl;
1458
0
  return Status::OK();
1459
0
}
1460
1461
0
Status ClusterAdminClient::DeleteNamespaceById(const NamespaceId& namespace_id) {
1462
0
  RETURN_NOT_OK(yb_client_->DeleteNamespace(
1463
0
      std::string() /* name */, boost::none /* database type */, namespace_id));
1464
0
  cout << "Deleted namespace " << namespace_id << endl;
1465
0
  return Status::OK();
1466
0
}
1467
1468
0
Status ClusterAdminClient::ListTabletsForTabletServer(const PeerId& ts_uuid) {
1469
0
  auto ts_addr = VERIFY_RESULT(GetFirstRpcAddressForTS(ts_uuid));
1470
1471
0
  TabletServerServiceProxy ts_proxy(proxy_cache_.get(), ts_addr);
1472
1473
0
  const auto resp = VERIFY_RESULT(InvokeRpc(
1474
0
      &TabletServerServiceProxy::ListTabletsForTabletServer, ts_proxy,
1475
0
      tserver::ListTabletsForTabletServerRequestPB()));
1476
1477
0
  cout << RightPadToWidth("Table name", kTableNameColWidth) << kColumnSep
1478
0
       << RightPadToUuidWidth("Tablet ID") << kColumnSep
1479
0
       << "Is Leader" << kColumnSep
1480
0
       << "State" << kColumnSep
1481
0
       << "Num SST Files" << kColumnSep
1482
0
       << "Num Log Segments" << kColumnSep
1483
0
       << "Num Memtables (Intents/Regular)" << endl;
1484
0
  for (const auto& entry : resp.entries()) {
1485
0
    cout << RightPadToWidth(entry.table_name(), kTableNameColWidth) << kColumnSep
1486
0
         << RightPadToUuidWidth(entry.tablet_id()) << kColumnSep
1487
0
         << entry.is_leader() << kColumnSep
1488
0
         << PBEnumToString(entry.state()) << kColumnSep
1489
0
         << entry.num_sst_files() << kColumnSep
1490
0
         << entry.num_log_segments() << kColumnSep
1491
0
         << entry.num_memtables_intents() << "/" << entry.num_memtables_regular() << endl;
1492
0
  }
1493
0
  return Status::OK();
1494
0
}
1495
1496
0
Status ClusterAdminClient::SetLoadBalancerEnabled(bool is_enabled) {
1497
0
  const auto list_resp = VERIFY_RESULT(InvokeRpc(
1498
0
      &master::MasterClusterProxy::ListMasters, *master_cluster_proxy_,
1499
0
      ListMastersRequestPB()));
1500
1501
0
  master::ChangeLoadBalancerStateRequestPB req;
1502
0
  req.set_is_enabled(is_enabled);
1503
0
  for (const auto& master : list_resp.masters()) {
1504
1505
0
    if (master.role() == PeerRole::LEADER) {
1506
0
      RETURN_NOT_OK(InvokeRpc(
1507
0
          &master::MasterClusterProxy::ChangeLoadBalancerState, *master_cluster_proxy_,
1508
0
          req));
1509
0
    } else {
1510
0
      HostPortPB hp_pb = master.registration().private_rpc_addresses(0);
1511
1512
0
      master::MasterClusterProxy proxy(proxy_cache_.get(), HostPortFromPB(hp_pb));
1513
0
      RETURN_NOT_OK(InvokeRpc(
1514
0
          &master::MasterClusterProxy::ChangeLoadBalancerState, proxy, req));
1515
0
    }
1516
0
  }
1517
1518
0
  return Status::OK();
1519
0
}
1520
1521
0
Status ClusterAdminClient::GetLoadBalancerState() {
1522
0
  const auto list_resp = VERIFY_RESULT(InvokeRpc(
1523
0
      &master::MasterClusterProxy::ListMasters, *master_cluster_proxy_,
1524
0
      ListMastersRequestPB()));
1525
1526
0
  if (list_resp.has_error()) {
1527
0
    LOG(ERROR) << "Error: querying leader master for live master info : "
1528
0
               << list_resp.error().DebugString() << endl;
1529
0
    return STATUS(RemoteError, list_resp.error().DebugString());
1530
0
  }
1531
1532
0
  cout << RightPadToUuidWidth("Master UUID") << kColumnSep
1533
0
       << RightPadToWidth(kRpcHostPortHeading, kHostPortColWidth) << kColumnSep
1534
0
       << RightPadToWidth("State", kSmallColWidth) << kColumnSep
1535
0
       << RightPadToWidth("Role", kSmallColWidth) << kColumnSep
1536
0
       << "Load Balancer State" << endl;
1537
1538
1539
0
  master::GetLoadBalancerStateRequestPB req;
1540
0
  master::GetLoadBalancerStateResponsePB resp;
1541
0
  string error;
1542
0
  master::MasterClusterProxy* proxy;
1543
0
  for (const auto& master : list_resp.masters()) {
1544
0
    error.clear();
1545
0
    std::unique_ptr<master::MasterClusterProxy> follower_proxy;
1546
0
    if (master.role() == PeerRole::LEADER) {
1547
0
      proxy = master_cluster_proxy_.get();
1548
0
    } else {
1549
0
      HostPortPB hp_pb = master.registration().private_rpc_addresses(0);
1550
0
      follower_proxy = std::make_unique<master::MasterClusterProxy>(
1551
0
          proxy_cache_.get(), HostPortFromPB(hp_pb));
1552
0
      proxy = follower_proxy.get();
1553
0
    }
1554
0
    auto result = InvokeRpc(&master::MasterClusterProxy::GetLoadBalancerState, *proxy, req);
1555
0
    if (!result) {
1556
0
      error = result.ToString();
1557
0
    } else {
1558
0
      resp = *result;
1559
0
      if (!resp.has_error()) {
1560
0
        error = resp.error().status().message();
1561
0
      }
1562
0
    }
1563
0
    const auto master_reg = master.has_registration() ? &master.registration() : nullptr;
1564
0
    cout << (master.has_instance_id() ? master.instance_id().permanent_uuid()
1565
0
                                      : RightPadToUuidWidth("UNKNOWN_UUID")) << kColumnSep;
1566
0
    cout << RightPadToWidth(
1567
0
        master_reg ? FormatFirstHostPort(master_reg->private_rpc_addresses())
1568
0
                   : "UNKNOWN", kHostPortColWidth)
1569
0
         << kColumnSep;
1570
0
    cout << RightPadToWidth((master.has_error() ?
1571
0
                             PBEnumToString(master.error().code()) : "ALIVE"), kSmallColWidth)
1572
0
         << kColumnSep;
1573
0
    cout << RightPadToWidth((master.has_role() ?
1574
0
                             PBEnumToString(master.role()) : "UNKNOWN"), kSmallColWidth)
1575
0
         << kColumnSep;
1576
0
    cout << (!error.empty() ? "Error: " + error : (resp.is_enabled() ? "ENABLED" : "DISABLED"))
1577
0
         << std::endl;
1578
0
  }
1579
1580
0
  return Status::OK();
1581
0
}
1582
1583
Status ClusterAdminClient::FlushTables(const std::vector<YBTableName>& table_names,
1584
                                       bool add_indexes,
1585
                                       int timeout_secs,
1586
2
                                       bool is_compaction) {
1587
2
  RETURN_NOT_OK(yb_client_->FlushTables(table_names, add_indexes, timeout_secs, is_compaction));
1588
2
  cout << (is_compaction ? 
"Compacted "0
: "Flushed ")
1589
2
       << ToString(table_names) << " tables"
1590
2
       << (add_indexes ? " and associated indexes." : 
"."0
) << endl;
1591
2
  return Status::OK();
1592
2
}
1593
1594
Status ClusterAdminClient::FlushTablesById(
1595
    const std::vector<TableId>& table_ids,
1596
    bool add_indexes,
1597
    int timeout_secs,
1598
0
    bool is_compaction) {
1599
0
  RETURN_NOT_OK(yb_client_->FlushTables(table_ids, add_indexes, timeout_secs, is_compaction));
1600
0
  cout << (is_compaction ? "Compacted " : "Flushed ")
1601
0
       << ToString(table_ids) << " tables"
1602
0
       << (add_indexes ? " and associated indexes." : ".") << endl;
1603
0
  return Status::OK();
1604
0
}
1605
1606
0
Status ClusterAdminClient::FlushSysCatalog() {
1607
0
  master::FlushSysCatalogRequestPB req;
1608
0
  auto res = InvokeRpc(
1609
0
      &master::MasterAdminProxy::FlushSysCatalog, *master_admin_proxy_, req);
1610
0
  return res.ok() ? Status::OK() : res.status();
1611
0
}
1612
1613
0
Status ClusterAdminClient::CompactSysCatalog() {
1614
0
  master::CompactSysCatalogRequestPB req;
1615
0
  auto res = InvokeRpc(
1616
0
      &master::MasterAdminProxy::CompactSysCatalog, *master_admin_proxy_, req);
1617
0
  return res.ok() ? Status::OK() : res.status();
1618
0
}
1619
1620
47
Status ClusterAdminClient::WaitUntilMasterLeaderReady() {
1621
47
  for(int iter = 0; iter < kNumberOfTryouts; 
++iter0
) {
1622
47
    const auto res_leader_ready = VERIFY_RESULT(InvokeRpcNoResponseCheck(
1623
47
        &master::MasterClusterProxy::IsMasterLeaderServiceReady,
1624
47
        *master_cluster_proxy_,  master::IsMasterLeaderReadyRequestPB(),
1625
47
        "MasterServiceImpl::IsMasterLeaderServiceReady call failed."));
1626
47
    if (!res_leader_ready.has_error()) {
1627
47
      return Status::OK();
1628
47
    }
1629
0
    sleep(kSleepTimeSec);
1630
0
  }
1631
0
  return STATUS(TimedOut, "ClusterAdminClient::WaitUntilMasterLeaderReady timed out.");
1632
47
}
1633
1634
Status ClusterAdminClient::AddReadReplicaPlacementInfo(
1635
1
    const string& placement_info, int replication_factor, const std::string& optional_uuid) {
1636
1
  RETURN_NOT_OK_PREPEND(WaitUntilMasterLeaderReady(), "Wait for master leader failed!");
1637
1638
  // Get the cluster config from the master leader.
1639
1
  auto resp_cluster_config = VERIFY_RESULT(GetMasterClusterConfig());
1640
1641
0
  auto* cluster_config = resp_cluster_config.mutable_cluster_config();
1642
1
  if (cluster_config->replication_info().read_replicas_size() > 0) {
1643
0
    return STATUS(InvalidCommand, "Already have a read replica placement, cannot add another.");
1644
0
  }
1645
1
  auto* read_replica_config = cluster_config->mutable_replication_info()->add_read_replicas();
1646
1647
  // If optional_uuid is set, make that the placement info, otherwise generate a random one.
1648
1
  string uuid_str = optional_uuid;
1649
1
  if (optional_uuid.empty()) {
1650
0
    uuid_str = RandomHumanReadableString(16);
1651
0
  }
1652
1
  read_replica_config->set_num_replicas(replication_factor);
1653
1
  read_replica_config->set_placement_uuid(uuid_str);
1654
1655
  // Fill in the placement info with new stuff.
1656
1
  RETURN_NOT_OK(FillPlacementInfo(read_replica_config, placement_info));
1657
1658
1
  master::ChangeMasterClusterConfigRequestPB req_new_cluster_config;
1659
1660
1
  *req_new_cluster_config.mutable_cluster_config() = *cluster_config;
1661
1662
1
  RETURN_NOT_OK(InvokeRpc(&master::MasterClusterProxy::ChangeMasterClusterConfig,
1663
1
                          *master_cluster_proxy_, req_new_cluster_config,
1664
1
                          "MasterServiceImpl::ChangeMasterClusterConfig call failed."));
1665
1666
1
  LOG(INFO) << "Created read replica placement with uuid: " << uuid_str;
1667
1
  return Status::OK();
1668
1
}
1669
1670
CHECKED_STATUS ClusterAdminClient::ModifyReadReplicaPlacementInfo(
1671
0
    const std::string& placement_uuid, const std::string& placement_info, int replication_factor) {
1672
0
  RETURN_NOT_OK_PREPEND(WaitUntilMasterLeaderReady(), "Wait for master leader failed!");
1673
1674
  // Get the cluster config from the master leader.
1675
0
  auto master_resp = VERIFY_RESULT(GetMasterClusterConfig());
1676
0
  auto* cluster_config = master_resp.mutable_cluster_config();
1677
1678
0
  auto* replication_info = cluster_config->mutable_replication_info();
1679
0
  if (replication_info->read_replicas_size() == 0) {
1680
0
    return STATUS(InvalidCommand, "No read replica placement info to modify.");
1681
0
  }
1682
1683
0
  auto* read_replica_config = replication_info->mutable_read_replicas(0);
1684
1685
0
  std::string config_placement_uuid;
1686
0
  if (placement_uuid.empty())  {
1687
    // If there is no placement_uuid set, use the existing uuid.
1688
0
    config_placement_uuid = read_replica_config->placement_uuid();
1689
0
  } else {
1690
    // Otherwise, use the passed in value.
1691
0
    config_placement_uuid = placement_uuid;
1692
0
  }
1693
1694
0
  read_replica_config->Clear();
1695
1696
0
  read_replica_config->set_num_replicas(replication_factor);
1697
0
  read_replica_config->set_placement_uuid(config_placement_uuid);
1698
0
  RETURN_NOT_OK(FillPlacementInfo(read_replica_config, placement_info));
1699
1700
0
  master::ChangeMasterClusterConfigRequestPB req_new_cluster_config;
1701
1702
0
  *req_new_cluster_config.mutable_cluster_config() = *cluster_config;
1703
1704
0
  RETURN_NOT_OK(InvokeRpc(&master::MasterClusterProxy::ChangeMasterClusterConfig,
1705
0
                          *master_cluster_proxy_, req_new_cluster_config,
1706
0
                          "MasterServiceImpl::ChangeMasterClusterConfig call failed."));
1707
1708
0
  LOG(INFO) << "Changed read replica placement.";
1709
0
  return Status::OK();
1710
0
}
1711
1712
0
CHECKED_STATUS ClusterAdminClient::DeleteReadReplicaPlacementInfo() {
1713
0
  RETURN_NOT_OK_PREPEND(WaitUntilMasterLeaderReady(), "Wait for master leader failed!");
1714
1715
0
  auto master_resp = VERIFY_RESULT(GetMasterClusterConfig());
1716
0
  auto* cluster_config = master_resp.mutable_cluster_config();
1717
1718
0
  auto* replication_info = cluster_config->mutable_replication_info();
1719
0
  if (replication_info->read_replicas_size() == 0) {
1720
0
    return STATUS(InvalidCommand, "No read replica placement info to delete.");
1721
0
  }
1722
1723
0
  replication_info->clear_read_replicas();
1724
1725
0
  master::ChangeMasterClusterConfigRequestPB req_new_cluster_config;
1726
1727
0
  *req_new_cluster_config.mutable_cluster_config() = *cluster_config;
1728
1729
0
  RETURN_NOT_OK(InvokeRpc(&master::MasterClusterProxy::ChangeMasterClusterConfig,
1730
0
                          *master_cluster_proxy_, req_new_cluster_config,
1731
0
                          "MasterServiceImpl::ChangeMasterClusterConfig call failed."));
1732
1733
0
  LOG(INFO) << "Deleted read replica placement.";
1734
0
  return Status::OK();
1735
0
}
1736
1737
Status ClusterAdminClient::FillPlacementInfo(
1738
1
    master::PlacementInfoPB* placement_info_pb, const string& placement_str) {
1739
1740
1
  std::vector<std::string> placement_info_split = strings::Split(
1741
1
      placement_str, ",", strings::SkipEmpty());
1742
1
  if (placement_info_split.size() < 1) {
1743
0
    return STATUS(InvalidCommand, "Cluster config must be a list of "
1744
0
                                  "placement infos seperated by commas. "
1745
0
                                  "Format: 'cloud1.region1.zone1:rf,cloud2.region2.zone2:rf, ..."
1746
0
        + std::to_string(placement_info_split.size()));
1747
0
  }
1748
1749
2
  
for (size_t iter = 0; 1
iter < placement_info_split.size();
iter++1
) {
1750
1
    std::vector<std::string> placement_block = strings::Split(placement_info_split[iter], ":",
1751
1
                                                              strings::SkipEmpty());
1752
1753
1
    if (placement_block.size() != 2) {
1754
0
      return STATUS(InvalidCommand, "Each placement info must be in format placement:rf");
1755
0
    }
1756
1757
1
    int min_num_replicas = VERIFY_RESULT(CheckedStoInt<int>(placement_block[1]));
1758
1759
0
    std::vector<std::string> block = strings::Split(placement_block[0], ".",
1760
1
                                                    strings::SkipEmpty());
1761
1
    if (block.size() != 3) {
1762
0
      return STATUS(InvalidCommand,
1763
0
          "Each placement info must have exactly 3 values seperated"
1764
0
          "by dots that denote cloud, region and zone. Block: " + placement_info_split[iter]
1765
0
          + " is invalid");
1766
0
    }
1767
1
    auto pb = placement_info_pb->add_placement_blocks();
1768
1
    pb->mutable_cloud_info()->set_placement_cloud(block[0]);
1769
1
    pb->mutable_cloud_info()->set_placement_region(block[1]);
1770
1
    pb->mutable_cloud_info()->set_placement_zone(block[2]);
1771
1772
1
    pb->set_min_num_replicas(min_num_replicas);
1773
1
  }
1774
1775
1
  return Status::OK();
1776
1
}
1777
1778
Status ClusterAdminClient::ModifyTablePlacementInfo(
1779
  const YBTableName& table_name, const std::string& placement_info, int replication_factor,
1780
4
  const std::string& optional_uuid) {
1781
1782
4
  YBTableName global_transactions(
1783
4
      YQL_DATABASE_CQL, master::kSystemNamespaceName, kGlobalTransactionsTableName);
1784
4
  if (table_name == global_transactions) {
1785
0
    return STATUS(InvalidCommand, "Placement cannot be modified for the global transactions table");
1786
0
  }
1787
1788
4
  std::vector<std::string> placement_info_split = strings::Split(
1789
4
      placement_info, ",", strings::SkipEmpty());
1790
4
  if (placement_info_split.size() < 1) {
1791
0
    return STATUS(InvalidCommand, "Table placement config must be a list of "
1792
0
    "placement infos seperated by commas. "
1793
0
    "Format: 'cloud1.region1.zone1,cloud2.region2.zone2,cloud3.region3.zone3 ..."
1794
0
    + std::to_string(placement_info_split.size()));
1795
0
  }
1796
1797
4
  master::PlacementInfoPB* live_replicas = new master::PlacementInfoPB;
1798
4
  live_replicas->set_num_replicas(replication_factor);
1799
  // Iterate over the placement blocks of the placementInfo structure.
1800
12
  for (size_t iter = 0; iter < placement_info_split.size(); 
iter++8
) {
1801
8
    std::vector<std::string> block = strings::Split(placement_info_split[iter], ".",
1802
8
                                                    strings::SkipEmpty());
1803
8
    if (block.size() != 3) {
1804
0
      return STATUS(InvalidCommand, "Each placement info must have exactly 3 values seperated"
1805
0
          "by dots that denote cloud, region and zone. Block: " + placement_info_split[iter]
1806
0
          + " is invalid");
1807
0
    }
1808
8
    auto pb = live_replicas->add_placement_blocks();
1809
8
    pb->mutable_cloud_info()->set_placement_cloud(block[0]);
1810
8
    pb->mutable_cloud_info()->set_placement_region(block[1]);
1811
8
    pb->mutable_cloud_info()->set_placement_zone(block[2]);
1812
    // TODO: Should this also be passed in as input?
1813
8
    pb->set_min_num_replicas(1);
1814
8
  }
1815
1816
4
  if (!optional_uuid.empty()) {
1817
    // If we have an optional uuid, set it.
1818
2
    live_replicas->set_placement_uuid(optional_uuid);
1819
2
  }
1820
1821
4
  return yb_client_->ModifyTablePlacementInfo(table_name, live_replicas);
1822
4
}
1823
1824
Status ClusterAdminClient::ModifyPlacementInfo(
1825
23
    std::string placement_info, int replication_factor, const std::string& optional_uuid) {
1826
1827
  // Wait to make sure that master leader is ready.
1828
23
  RETURN_NOT_OK_PREPEND(WaitUntilMasterLeaderReady(), "Wait for master leader failed!");
1829
1830
  // Get the cluster config from the master leader.
1831
23
  auto resp_cluster_config = 
VERIFY_RESULT16
(GetMasterClusterConfig());16
1832
1833
  // Create a new cluster config.
1834
0
  std::vector<std::string> placement_info_split = strings::Split(
1835
16
      placement_info, ",", strings::AllowEmpty());
1836
16
  if (placement_info_split.size() < 1) {
1837
0
    return STATUS(
1838
0
        InvalidCommand,
1839
0
        "Cluster config must be a list of placement infos seperated by commas. Format: "
1840
0
        "cloud1.region1.zone1:[min_replica_count1],cloud2.region2.zone2:[min_replica_count2] ..."
1841
0
        + std::to_string(placement_info_split.size()));
1842
0
  }
1843
16
  master::ChangeMasterClusterConfigRequestPB req_new_cluster_config;
1844
16
  master::SysClusterConfigEntryPB* sys_cluster_config_entry =
1845
16
      resp_cluster_config.mutable_cluster_config();
1846
16
  master::PlacementInfoPB* live_replicas = new master::PlacementInfoPB;
1847
16
  live_replicas->set_num_replicas(replication_factor);
1848
1849
16
  int total_min_replica_count = 0;
1850
1851
  // Iterate over the placement blocks of the placementInfo structure.
1852
16
  std::unordered_map<std::string, int> placement_to_min_replicas;
1853
44
  for (const auto& placement_block : placement_info_split) {
1854
44
    std::vector<std::string> placement_info_min_replica_split =
1855
44
        strings::Split(placement_block, ":", strings::AllowEmpty());
1856
1857
44
    if (placement_info_min_replica_split.size() == 0 ||
1858
44
        placement_info_min_replica_split.size() > 2) {
1859
0
      return STATUS(
1860
0
          InvalidCommand,
1861
0
          "Each placement info must have at most 2 values separated by a colon. "
1862
0
          "Format: cloud.region.zone:[min_replica_count]. Invalid placement info: "
1863
0
          + placement_block);
1864
0
    }
1865
1866
44
    std::string placement_target = placement_info_min_replica_split[0];
1867
44
    int placement_min_replica_count = 1;
1868
1869
44
    if (placement_info_min_replica_split.size() == 2) {
1870
2
      placement_min_replica_count = VERIFY_RESULT(CheckedStoi(placement_info_min_replica_split[1]));
1871
2
    }
1872
1873
44
    total_min_replica_count += placement_min_replica_count;
1874
44
    placement_to_min_replicas[placement_target] += placement_min_replica_count;
1875
44
  }
1876
1877
16
  if (total_min_replica_count > replication_factor) {
1878
0
    return STATUS(
1879
0
        InvalidCommand,
1880
0
        "replication_factor should be greater than or equal to the total of replica counts "
1881
0
        "specified in placement_info.");
1882
0
  }
1883
1884
41
  
for (const auto& placement_block : placement_to_min_replicas)16
{
1885
41
    std::vector<std::string> block = strings::Split(placement_block.first, ".",
1886
41
                                                    strings::AllowEmpty());
1887
41
    auto pb = live_replicas->add_placement_blocks();
1888
41
    if (block.size() > 0 && block[0] != "") {
1889
41
      pb->mutable_cloud_info()->set_placement_cloud(block[0]);
1890
41
    }
1891
1892
41
    if (block.size() > 1 && block[1] != "") {
1893
41
      pb->mutable_cloud_info()->set_placement_region(block[1]);
1894
41
    }
1895
1896
41
    if (block.size() > 2 && 
block[2] != ""40
) {
1897
40
      pb->mutable_cloud_info()->set_placement_zone(block[2]);
1898
40
    }
1899
1900
41
    pb->set_min_num_replicas(placement_block.second);
1901
41
  }
1902
1903
16
  if (!optional_uuid.empty()) {
1904
    // If we have an optional uuid, set it.
1905
2
    live_replicas->set_placement_uuid(optional_uuid);
1906
14
  } else if (sys_cluster_config_entry->replication_info().live_replicas().has_placement_uuid()) {
1907
    // Otherwise, if we have an existing placement uuid, use that.
1908
0
    live_replicas->set_placement_uuid(
1909
0
        sys_cluster_config_entry->replication_info().live_replicas().placement_uuid());
1910
0
  }
1911
1912
16
  sys_cluster_config_entry->mutable_replication_info()->set_allocated_live_replicas(live_replicas);
1913
16
  req_new_cluster_config.mutable_cluster_config()->CopyFrom(*sys_cluster_config_entry);
1914
1915
16
  RETURN_NOT_OK(InvokeRpc(
1916
16
      &master::MasterClusterProxy::ChangeMasterClusterConfig, *master_cluster_proxy_,
1917
16
      req_new_cluster_config, "MasterServiceImpl::ChangeMasterClusterConfig call failed."));
1918
1919
16
  LOG(INFO) << "Changed master cluster config.";
1920
16
  return Status::OK();
1921
16
}
1922
1923
1
Status ClusterAdminClient::ClearPlacementInfo() {
1924
  // Wait to make sure that master leader is ready.
1925
1
  RETURN_NOT_OK_PREPEND(WaitUntilMasterLeaderReady(), "Wait for master leader failed!");
1926
1927
  // Get the cluster config from the master leader.
1928
1
  auto resp_cluster_config = VERIFY_RESULT(GetMasterClusterConfig());
1929
1930
0
  master::SysClusterConfigEntryPB* sys_cluster_config_entry =
1931
1
      resp_cluster_config.mutable_cluster_config();
1932
1
  sys_cluster_config_entry->clear_replication_info();
1933
1934
1
  master::ChangeMasterClusterConfigRequestPB req_new_cluster_config;
1935
1
  req_new_cluster_config.mutable_cluster_config()->CopyFrom(*sys_cluster_config_entry);
1936
1937
1
  RETURN_NOT_OK(InvokeRpc(
1938
1
      &master::MasterClusterProxy::ChangeMasterClusterConfig, *master_cluster_proxy_,
1939
1
      req_new_cluster_config, "MasterServiceImpl::ChangeMasterClusterConfig call failed."));
1940
1941
1
  LOG(INFO) << "Cleared master placement info config";
1942
1
  return Status::OK();
1943
1
}
1944
1945
7
Status ClusterAdminClient::GetUniverseConfig() {
1946
7
  const auto cluster_config = VERIFY_RESULT(GetMasterClusterConfig());
1947
0
  std::string output;
1948
7
  MessageToJsonString(cluster_config.cluster_config(), &output);
1949
7
  cout << output << endl;
1950
7
  return Status::OK();
1951
7
}
1952
1953
0
Status ClusterAdminClient::GetYsqlCatalogVersion() {
1954
0
  uint64_t version = 0;
1955
0
  RETURN_NOT_OK(yb_client_->GetYsqlCatalogMasterVersion(&version));
1956
0
  cout << "Version: "  << version << endl;
1957
0
  return Status::OK();
1958
0
}
1959
1960
1
Result<rapidjson::Document> ClusterAdminClient::DdlLog() {
1961
1
  RpcController rpc;
1962
1
  rpc.set_timeout(timeout_);
1963
1
  master::DdlLogRequestPB req;
1964
1
  master::DdlLogResponsePB resp;
1965
1966
1
  RETURN_NOT_OK(master_admin_proxy_->DdlLog(req, &resp, &rpc));
1967
1968
1
  if (resp.has_error()) {
1969
0
    return StatusFromPB(resp.error().status());
1970
0
  }
1971
1972
1
  rapidjson::Document result;
1973
1
  result.SetObject();
1974
1
  rapidjson::Value json_entries(rapidjson::kArrayType);
1975
3
  for (const auto& entry : resp.entries()) {
1976
3
    rapidjson::Value json_entry(rapidjson::kObjectType);
1977
3
    AddStringField("table_type", TableType_Name(entry.table_type()), &json_entry,
1978
3
                   &result.GetAllocator());
1979
3
    AddStringField("namespace", entry.namespace_name(), &json_entry, &result.GetAllocator());
1980
3
    AddStringField("table", entry.table_name(), &json_entry, &result.GetAllocator());
1981
3
    AddStringField("action", entry.action(), &json_entry, &result.GetAllocator());
1982
3
    AddStringField("time", HybridTimeToString(HybridTime(entry.time())),
1983
3
                   &json_entry, &result.GetAllocator());
1984
3
    json_entries.PushBack(json_entry, result.GetAllocator());
1985
3
  }
1986
1
  result.AddMember("log", json_entries, result.GetAllocator());
1987
1
  return result;
1988
1
}
1989
1990
1
Status ClusterAdminClient::UpgradeYsql() {
1991
1
  {
1992
1
    master::IsInitDbDoneRequestPB req;
1993
1
    auto res = InvokeRpc(
1994
1
        &master::MasterAdminProxy::IsInitDbDone, *master_admin_proxy_, req);
1995
1
    if (!res.ok()) {
1996
0
      return res.status();
1997
0
    }
1998
1
    if (!res->done()) {
1999
0
      cout << "Upgrade is not needed since YSQL is disabled" << endl;
2000
0
      return Status::OK();
2001
0
    }
2002
1
    if (res->done() && res->has_error()) {
2003
0
      return STATUS_FORMAT(IllegalState,
2004
0
                           "YSQL is not ready, initdb finished with an error: $0",
2005
0
                           res->error());
2006
0
    }
2007
    // Otherwise, we can proceed.
2008
1
  }
2009
2010
  // Pick some alive TServer.
2011
1
  RepeatedPtrField<ListTabletServersResponsePB::Entry> servers;
2012
1
  RETURN_NOT_OK(ListTabletServers(&servers));
2013
1
  boost::optional<HostPortPB> ts_rpc_addr;
2014
1
  for (const ListTabletServersResponsePB::Entry& server : servers) {
2015
1
    if (!server.has_alive() || !server.alive()) {
2016
0
      continue;
2017
0
    }
2018
2019
1
    if (!server.has_registration() ||
2020
1
        server.registration().common().private_rpc_addresses().empty()) {
2021
0
      continue;
2022
0
    }
2023
2024
1
    ts_rpc_addr.emplace(server.registration().common().private_rpc_addresses(0));
2025
1
    break;
2026
1
  }
2027
1
  if (!ts_rpc_addr.has_value()) {
2028
0
    return STATUS(IllegalState, "Couldn't find alive tablet server to connect to");
2029
0
  }
2030
2031
1
  TabletServerAdminServiceProxy ts_admin_proxy(proxy_cache_.get(), HostPortFromPB(*ts_rpc_addr));
2032
2033
1
  UpgradeYsqlRequestPB req;
2034
1
  const auto resp_result = InvokeRpc(&TabletServerAdminServiceProxy::UpgradeYsql,
2035
1
                                     ts_admin_proxy, req);
2036
1
  if (!resp_result.ok()) {
2037
0
    return resp_result.status();
2038
0
  }
2039
1
  if (resp_result->has_error()) {
2040
0
    return StatusFromPB(resp_result->error().status());
2041
0
  }
2042
2043
1
  cout << "YSQL successfully upgraded to the latest version" << endl;
2044
1
  return Status::OK();
2045
1
}
2046
2047
Status ClusterAdminClient::ChangeBlacklist(const std::vector<HostPort>& servers, bool add,
2048
2
    bool blacklist_leader) {
2049
2
  auto config = VERIFY_RESULT(GetMasterClusterConfig());
2050
0
  auto& cluster_config = *config.mutable_cluster_config();
2051
2
  auto& blacklist = (blacklist_leader) ?
2052
0
    *cluster_config.mutable_leader_blacklist() :
2053
2
    *cluster_config.mutable_server_blacklist();
2054
2
  std::vector<HostPort> result_blacklist;
2055
3
  for (const auto& host : blacklist.hosts()) {
2056
3
    const HostPort hostport(host.host(), host.port());
2057
3
    if (std::find(servers.begin(), servers.end(), hostport) == servers.end()) {
2058
2
      result_blacklist.emplace_back(host.host(), host.port());
2059
2
    }
2060
3
  }
2061
2
  if (add) {
2062
1
    result_blacklist.insert(result_blacklist.end(), servers.begin(), servers.end());
2063
1
  }
2064
2
  auto result_begin = result_blacklist.begin(), result_end = result_blacklist.end();
2065
2
  std::sort(result_begin, result_end);
2066
2
  result_blacklist.erase(std::unique(result_begin, result_end), result_end);
2067
2
  blacklist.clear_hosts();
2068
5
  for (const auto& hostport : result_blacklist) {
2069
5
    auto& new_host = *blacklist.add_hosts();
2070
5
    new_host.set_host(hostport.host());
2071
5
    new_host.set_port(hostport.port());
2072
5
  }
2073
2
  master::ChangeMasterClusterConfigRequestPB req_new_cluster_config;
2074
2
  req_new_cluster_config.mutable_cluster_config()->Swap(&cluster_config);
2075
2
  return ResultToStatus(InvokeRpc(&master::MasterClusterProxy::ChangeMasterClusterConfig,
2076
2
                                  *master_cluster_proxy_, req_new_cluster_config,
2077
2
                                  "MasterServiceImpl::ChangeMasterClusterConfig call failed."));
2078
2
}
2079
2080
Result<const master::NamespaceIdentifierPB&> ClusterAdminClient::GetNamespaceInfo(
2081
0
    YQLDatabase db_type, const std::string& namespace_name) {
2082
0
  LOG(INFO) << Format(
2083
0
      "Resolving namespace id for '$0' of type '$1'", namespace_name, DatabasePrefix(db_type));
2084
0
  for (const auto& item : VERIFY_RESULT_REF(GetNamespaceMap())) {
2085
0
    const auto& namespace_info = item.second;
2086
0
    if (namespace_info.database_type() == db_type && namespace_name == namespace_info.name()) {
2087
0
      return namespace_info;
2088
0
    }
2089
0
  }
2090
0
  return STATUS_FORMAT(
2091
0
      NotFound, "Namespace '$0' of type '$1' not found", namespace_name, DatabasePrefix(db_type));
2092
0
}
2093
2094
34
Result<master::GetMasterClusterConfigResponsePB> ClusterAdminClient::GetMasterClusterConfig() {
2095
34
  return InvokeRpc(&master::MasterClusterProxy::GetMasterClusterConfig,
2096
34
                   *master_cluster_proxy_, master::GetMasterClusterConfigRequestPB(),
2097
34
                   "MasterServiceImpl::GetMasterClusterConfig call failed.");
2098
34
}
2099
2100
0
CHECKED_STATUS ClusterAdminClient::SplitTablet(const std::string& tablet_id) {
2101
0
  master::SplitTabletRequestPB req;
2102
0
  req.set_tablet_id(tablet_id);
2103
0
  const auto resp = VERIFY_RESULT(InvokeRpc(
2104
0
      &master::MasterAdminProxy::SplitTablet, *master_admin_proxy_, req));
2105
0
  std::cout << "Response: " << AsString(resp) << std::endl;
2106
0
  return Status::OK();
2107
0
}
2108
2109
0
CHECKED_STATUS ClusterAdminClient::DisableTabletSplitting(int64_t disable_duration_ms) {
2110
0
  master::DisableTabletSplittingRequestPB req;
2111
0
  req.set_disable_duration_ms(disable_duration_ms);
2112
0
  const auto resp = VERIFY_RESULT(
2113
0
      InvokeRpc(&master::MasterAdminProxy::DisableTabletSplitting, *master_admin_proxy_, req));
2114
0
  std::cout << "Response: " << AsString(resp) << std::endl;
2115
0
  return Status::OK();
2116
0
}
2117
2118
0
CHECKED_STATUS ClusterAdminClient::IsTabletSplittingComplete() {
2119
0
  master::IsTabletSplittingCompleteRequestPB req;
2120
0
  const auto resp = VERIFY_RESULT(
2121
0
      InvokeRpc(&master::MasterAdminProxy::IsTabletSplittingComplete, *master_admin_proxy_, req));
2122
0
  std::cout << "Response: " << AsString(resp) << std::endl;
2123
0
  return Status::OK();
2124
0
}
2125
2126
0
Status ClusterAdminClient::CreateTransactionsStatusTable(const std::string& table_name) {
2127
0
  return yb_client_->CreateTransactionsStatusTable(table_name);
2128
0
}
2129
2130
template<class Response, class Request, class Object>
2131
Result<Response> ClusterAdminClient::InvokeRpcNoResponseCheck(
2132
    Status (Object::*func)(const Request&, Response*, rpc::RpcController*) const,
2133
264
    const Object& obj, const Request& req, const char* error_message) {
2134
264
  rpc::RpcController rpc;
2135
264
  rpc.set_timeout(timeout_);
2136
264
  Response response;
2137
264
  auto result = (obj.*func)(req, &response, &rpc);
2138
264
  if (error_message) {
2139
101
    RETURN_NOT_OK_PREPEND(result, error_message);
2140
163
  } else {
2141
163
    RETURN_NOT_OK(result);
2142
163
  }
2143
257
  return std::move(response);
2144
264
}
yb::Result<yb::master::ListMastersResponsePB> yb::tools::ClusterAdminClient::InvokeRpcNoResponseCheck<yb::master::ListMastersResponsePB, yb::master::ListMastersRequestPB, yb::master::MasterClusterProxy>(yb::Status (yb::master::MasterClusterProxy::*)(yb::master::ListMastersRequestPB const&, yb::master::ListMastersResponsePB*, yb::rpc::RpcController*) const, yb::master::MasterClusterProxy const&, yb::master::ListMastersRequestPB const&, char const*)
Line
Count
Source
2133
18
    const Object& obj, const Request& req, const char* error_message) {
2134
18
  rpc::RpcController rpc;
2135
18
  rpc.set_timeout(timeout_);
2136
18
  Response response;
2137
18
  auto result = (obj.*func)(req, &response, &rpc);
2138
18
  if (error_message) {
2139
0
    RETURN_NOT_OK_PREPEND(result, error_message);
2140
18
  } else {
2141
18
    RETURN_NOT_OK(result);
2142
18
  }
2143
18
  return std::move(response);
2144
18
}
yb::Result<yb::consensus::LeaderStepDownResponsePB> yb::tools::ClusterAdminClient::InvokeRpcNoResponseCheck<yb::consensus::LeaderStepDownResponsePB, yb::consensus::LeaderStepDownRequestPB, yb::consensus::ConsensusServiceProxy>(yb::Status (yb::consensus::ConsensusServiceProxy::*)(yb::consensus::LeaderStepDownRequestPB const&, yb::consensus::LeaderStepDownResponsePB*, yb::rpc::RpcController*) const, yb::consensus::ConsensusServiceProxy const&, yb::consensus::LeaderStepDownRequestPB const&, char const*)
Line
Count
Source
2133
4
    const Object& obj, const Request& req, const char* error_message) {
2134
4
  rpc::RpcController rpc;
2135
4
  rpc.set_timeout(timeout_);
2136
4
  Response response;
2137
4
  auto result = (obj.*func)(req, &response, &rpc);
2138
4
  if (error_message) {
2139
0
    RETURN_NOT_OK_PREPEND(result, error_message);
2140
4
  } else {
2141
4
    RETURN_NOT_OK(result);
2142
4
  }
2143
4
  return std::move(response);
2144
4
}
Unexecuted instantiation: yb::Result<yb::consensus::RunLeaderElectionResponsePB> yb::tools::ClusterAdminClient::InvokeRpcNoResponseCheck<yb::consensus::RunLeaderElectionResponsePB, yb::consensus::RunLeaderElectionRequestPB, yb::consensus::ConsensusServiceProxy>(yb::Status (yb::consensus::ConsensusServiceProxy::*)(yb::consensus::RunLeaderElectionRequestPB const&, yb::consensus::RunLeaderElectionResponsePB*, yb::rpc::RpcController*) const, yb::consensus::ConsensusServiceProxy const&, yb::consensus::RunLeaderElectionRequestPB const&, char const*)
yb::Result<yb::consensus::ChangeConfigResponsePB> yb::tools::ClusterAdminClient::InvokeRpcNoResponseCheck<yb::consensus::ChangeConfigResponsePB, yb::consensus::ChangeConfigRequestPB, yb::consensus::ConsensusServiceProxy>(yb::Status (yb::consensus::ConsensusServiceProxy::*)(yb::consensus::ChangeConfigRequestPB const&, yb::consensus::ChangeConfigResponsePB*, yb::rpc::RpcController*) const, yb::consensus::ConsensusServiceProxy const&, yb::consensus::ChangeConfigRequestPB const&, char const*)
Line
Count
Source
2133
3
    const Object& obj, const Request& req, const char* error_message) {
2134
3
  rpc::RpcController rpc;
2135
3
  rpc.set_timeout(timeout_);
2136
3
  Response response;
2137
3
  auto result = (obj.*func)(req, &response, &rpc);
2138
3
  if (error_message) {
2139
0
    RETURN_NOT_OK_PREPEND(result, error_message);
2140
3
  } else {
2141
3
    RETURN_NOT_OK(result);
2142
3
  }
2143
3
  return std::move(response);
2144
3
}
Unexecuted instantiation: yb::Result<yb::master::DumpMasterStateResponsePB> yb::tools::ClusterAdminClient::InvokeRpcNoResponseCheck<yb::master::DumpMasterStateResponsePB, yb::master::DumpMasterStateRequestPB, yb::master::MasterClusterProxy>(yb::Status (yb::master::MasterClusterProxy::*)(yb::master::DumpMasterStateRequestPB const&, yb::master::DumpMasterStateResponsePB*, yb::rpc::RpcController*) const, yb::master::MasterClusterProxy const&, yb::master::DumpMasterStateRequestPB const&, char const*)
Unexecuted instantiation: yb::Result<yb::master::GetLoadMovePercentResponsePB> yb::tools::ClusterAdminClient::InvokeRpcNoResponseCheck<yb::master::GetLoadMovePercentResponsePB, yb::master::GetLoadMovePercentRequestPB, yb::master::MasterClusterProxy>(yb::Status (yb::master::MasterClusterProxy::*)(yb::master::GetLoadMovePercentRequestPB const&, yb::master::GetLoadMovePercentResponsePB*, yb::rpc::RpcController*) const, yb::master::MasterClusterProxy const&, yb::master::GetLoadMovePercentRequestPB const&, char const*)
Unexecuted instantiation: yb::Result<yb::master::GetLoadMovePercentResponsePB> yb::tools::ClusterAdminClient::InvokeRpcNoResponseCheck<yb::master::GetLoadMovePercentResponsePB, yb::master::GetLeaderBlacklistPercentRequestPB, yb::master::MasterClusterProxy>(yb::Status (yb::master::MasterClusterProxy::*)(yb::master::GetLeaderBlacklistPercentRequestPB const&, yb::master::GetLoadMovePercentResponsePB*, yb::rpc::RpcController*) const, yb::master::MasterClusterProxy const&, yb::master::GetLeaderBlacklistPercentRequestPB const&, char const*)
yb::Result<yb::master::GetTabletLocationsResponsePB> yb::tools::ClusterAdminClient::InvokeRpcNoResponseCheck<yb::master::GetTabletLocationsResponsePB, yb::master::GetTabletLocationsRequestPB, yb::master::MasterClientProxy>(yb::Status (yb::master::MasterClientProxy::*)(yb::master::GetTabletLocationsRequestPB const&, yb::master::GetTabletLocationsResponsePB*, yb::rpc::RpcController*) const, yb::master::MasterClientProxy const&, yb::master::GetTabletLocationsRequestPB const&, char const*)
Line
Count
Source
2133
134
    const Object& obj, const Request& req, const char* error_message) {
2134
134
  rpc::RpcController rpc;
2135
134
  rpc.set_timeout(timeout_);
2136
134
  Response response;
2137
134
  auto result = (obj.*func)(req, &response, &rpc);
2138
134
  if (error_message) {
2139
0
    RETURN_NOT_OK_PREPEND(result, error_message);
2140
134
  } else {
2141
134
    RETURN_NOT_OK(result);
2142
134
  }
2143
134
  return std::move(response);
2144
134
}
yb::Result<yb::master::ListTabletServersResponsePB> yb::tools::ClusterAdminClient::InvokeRpcNoResponseCheck<yb::master::ListTabletServersResponsePB, yb::master::ListTabletServersRequestPB, yb::master::MasterClusterProxy>(yb::Status (yb::master::MasterClusterProxy::*)(yb::master::ListTabletServersRequestPB const&, yb::master::ListTabletServersResponsePB*, yb::rpc::RpcController*) const, yb::master::MasterClusterProxy const&, yb::master::ListTabletServersRequestPB const&, char const*)
Line
Count
Source
2133
1
    const Object& obj, const Request& req, const char* error_message) {
2134
1
  rpc::RpcController rpc;
2135
1
  rpc.set_timeout(timeout_);
2136
1
  Response response;
2137
1
  auto result = (obj.*func)(req, &response, &rpc);
2138
1
  if (error_message) {
2139
0
    RETURN_NOT_OK_PREPEND(result, error_message);
2140
1
  } else {
2141
1
    RETURN_NOT_OK(result);
2142
1
  }
2143
1
  return std::move(response);
2144
1
}
Unexecuted instantiation: yb::Result<yb::tserver::GetLogLocationResponsePB> yb::tools::ClusterAdminClient::InvokeRpcNoResponseCheck<yb::tserver::GetLogLocationResponsePB, yb::tserver::GetLogLocationRequestPB, yb::tserver::TabletServerServiceProxy>(yb::Status (yb::tserver::TabletServerServiceProxy::*)(yb::tserver::GetLogLocationRequestPB const&, yb::tserver::GetLogLocationResponsePB*, yb::rpc::RpcController*) const, yb::tserver::TabletServerServiceProxy const&, yb::tserver::GetLogLocationRequestPB const&, char const*)
yb::Result<yb::master::LaunchBackfillIndexForTableResponsePB> yb::tools::ClusterAdminClient::InvokeRpcNoResponseCheck<yb::master::LaunchBackfillIndexForTableResponsePB, yb::master::LaunchBackfillIndexForTableRequestPB, yb::master::MasterDdlProxy>(yb::Status (yb::master::MasterDdlProxy::*)(yb::master::LaunchBackfillIndexForTableRequestPB const&, yb::master::LaunchBackfillIndexForTableResponsePB*, yb::rpc::RpcController*) const, yb::master::MasterDdlProxy const&, yb::master::LaunchBackfillIndexForTableRequestPB const&, char const*)
Line
Count
Source
2133
1
    const Object& obj, const Request& req, const char* error_message) {
2134
1
  rpc::RpcController rpc;
2135
1
  rpc.set_timeout(timeout_);
2136
1
  Response response;
2137
1
  auto result = (obj.*func)(req, &response, &rpc);
2138
1
  if (error_message) {
2139
0
    RETURN_NOT_OK_PREPEND(result, error_message);
2140
1
  } else {
2141
1
    RETURN_NOT_OK(result);
2142
1
  }
2143
1
  return std::move(response);
2144
1
}
Unexecuted instantiation: yb::Result<yb::tserver::ListTabletsForTabletServerResponsePB> yb::tools::ClusterAdminClient::InvokeRpcNoResponseCheck<yb::tserver::ListTabletsForTabletServerResponsePB, yb::tserver::ListTabletsForTabletServerRequestPB, yb::tserver::TabletServerServiceProxy>(yb::Status (yb::tserver::TabletServerServiceProxy::*)(yb::tserver::ListTabletsForTabletServerRequestPB const&, yb::tserver::ListTabletsForTabletServerResponsePB*, yb::rpc::RpcController*) const, yb::tserver::TabletServerServiceProxy const&, yb::tserver::ListTabletsForTabletServerRequestPB const&, char const*)
Unexecuted instantiation: yb::Result<yb::master::ChangeLoadBalancerStateResponsePB> yb::tools::ClusterAdminClient::InvokeRpcNoResponseCheck<yb::master::ChangeLoadBalancerStateResponsePB, yb::master::ChangeLoadBalancerStateRequestPB, yb::master::MasterClusterProxy>(yb::Status (yb::master::MasterClusterProxy::*)(yb::master::ChangeLoadBalancerStateRequestPB const&, yb::master::ChangeLoadBalancerStateResponsePB*, yb::rpc::RpcController*) const, yb::master::MasterClusterProxy const&, yb::master::ChangeLoadBalancerStateRequestPB const&, char const*)
Unexecuted instantiation: yb::Result<yb::master::GetLoadBalancerStateResponsePB> yb::tools::ClusterAdminClient::InvokeRpcNoResponseCheck<yb::master::GetLoadBalancerStateResponsePB, yb::master::GetLoadBalancerStateRequestPB, yb::master::MasterClusterProxy>(yb::Status (yb::master::MasterClusterProxy::*)(yb::master::GetLoadBalancerStateRequestPB const&, yb::master::GetLoadBalancerStateResponsePB*, yb::rpc::RpcController*) const, yb::master::MasterClusterProxy const&, yb::master::GetLoadBalancerStateRequestPB const&, char const*)
Unexecuted instantiation: yb::Result<yb::master::FlushSysCatalogResponsePB> yb::tools::ClusterAdminClient::InvokeRpcNoResponseCheck<yb::master::FlushSysCatalogResponsePB, yb::master::FlushSysCatalogRequestPB, yb::master::MasterAdminProxy>(yb::Status (yb::master::MasterAdminProxy::*)(yb::master::FlushSysCatalogRequestPB const&, yb::master::FlushSysCatalogResponsePB*, yb::rpc::RpcController*) const, yb::master::MasterAdminProxy const&, yb::master::FlushSysCatalogRequestPB const&, char const*)
Unexecuted instantiation: yb::Result<yb::master::CompactSysCatalogResponsePB> yb::tools::ClusterAdminClient::InvokeRpcNoResponseCheck<yb::master::CompactSysCatalogResponsePB, yb::master::CompactSysCatalogRequestPB, yb::master::MasterAdminProxy>(yb::Status (yb::master::MasterAdminProxy::*)(yb::master::CompactSysCatalogRequestPB const&, yb::master::CompactSysCatalogResponsePB*, yb::rpc::RpcController*) const, yb::master::MasterAdminProxy const&, yb::master::CompactSysCatalogRequestPB const&, char const*)
yb::Result<yb::master::IsMasterLeaderReadyResponsePB> yb::tools::ClusterAdminClient::InvokeRpcNoResponseCheck<yb::master::IsMasterLeaderReadyResponsePB, yb::master::IsMasterLeaderReadyRequestPB, yb::master::MasterClusterProxy>(yb::Status (yb::master::MasterClusterProxy::*)(yb::master::IsMasterLeaderReadyRequestPB const&, yb::master::IsMasterLeaderReadyResponsePB*, yb::rpc::RpcController*) const, yb::master::MasterClusterProxy const&, yb::master::IsMasterLeaderReadyRequestPB const&, char const*)
Line
Count
Source
2133
47
    const Object& obj, const Request& req, const char* error_message) {
2134
47
  rpc::RpcController rpc;
2135
47
  rpc.set_timeout(timeout_);
2136
47
  Response response;
2137
47
  auto result = (obj.*func)(req, &response, &rpc);
2138
47
  if (error_message) {
2139
47
    RETURN_NOT_OK_PREPEND(result, error_message);
2140
47
  } else {
2141
0
    RETURN_NOT_OK(result);
2142
0
  }
2143
47
  return std::move(response);
2144
47
}
yb::Result<yb::master::ChangeMasterClusterConfigResponsePB> yb::tools::ClusterAdminClient::InvokeRpcNoResponseCheck<yb::master::ChangeMasterClusterConfigResponsePB, yb::master::ChangeMasterClusterConfigRequestPB, yb::master::MasterClusterProxy>(yb::Status (yb::master::MasterClusterProxy::*)(yb::master::ChangeMasterClusterConfigRequestPB const&, yb::master::ChangeMasterClusterConfigResponsePB*, yb::rpc::RpcController*) const, yb::master::MasterClusterProxy const&, yb::master::ChangeMasterClusterConfigRequestPB const&, char const*)
Line
Count
Source
2133
20
    const Object& obj, const Request& req, const char* error_message) {
2134
20
  rpc::RpcController rpc;
2135
20
  rpc.set_timeout(timeout_);
2136
20
  Response response;
2137
20
  auto result = (obj.*func)(req, &response, &rpc);
2138
20
  if (error_message) {
2139
20
    RETURN_NOT_OK_PREPEND(result, error_message);
2140
20
  } else {
2141
0
    RETURN_NOT_OK(result);
2142
0
  }
2143
20
  return std::move(response);
2144
20
}
yb::Result<yb::master::IsInitDbDoneResponsePB> yb::tools::ClusterAdminClient::InvokeRpcNoResponseCheck<yb::master::IsInitDbDoneResponsePB, yb::master::IsInitDbDoneRequestPB, yb::master::MasterAdminProxy>(yb::Status (yb::master::MasterAdminProxy::*)(yb::master::IsInitDbDoneRequestPB const&, yb::master::IsInitDbDoneResponsePB*, yb::rpc::RpcController*) const, yb::master::MasterAdminProxy const&, yb::master::IsInitDbDoneRequestPB const&, char const*)
Line
Count
Source
2133
1
    const Object& obj, const Request& req, const char* error_message) {
2134
1
  rpc::RpcController rpc;
2135
1
  rpc.set_timeout(timeout_);
2136
1
  Response response;
2137
1
  auto result = (obj.*func)(req, &response, &rpc);
2138
1
  if (error_message) {
2139
0
    RETURN_NOT_OK_PREPEND(result, error_message);
2140
1
  } else {
2141
1
    RETURN_NOT_OK(result);
2142
1
  }
2143
1
  return std::move(response);
2144
1
}
yb::Result<yb::tserver::UpgradeYsqlResponsePB> yb::tools::ClusterAdminClient::InvokeRpcNoResponseCheck<yb::tserver::UpgradeYsqlResponsePB, yb::tserver::UpgradeYsqlRequestPB, yb::tserver::TabletServerAdminServiceProxy>(yb::Status (yb::tserver::TabletServerAdminServiceProxy::*)(yb::tserver::UpgradeYsqlRequestPB const&, yb::tserver::UpgradeYsqlResponsePB*, yb::rpc::RpcController*) const, yb::tserver::TabletServerAdminServiceProxy const&, yb::tserver::UpgradeYsqlRequestPB const&, char const*)
Line
Count
Source
2133
1
    const Object& obj, const Request& req, const char* error_message) {
2134
1
  rpc::RpcController rpc;
2135
1
  rpc.set_timeout(timeout_);
2136
1
  Response response;
2137
1
  auto result = (obj.*func)(req, &response, &rpc);
2138
1
  if (error_message) {
2139
0
    RETURN_NOT_OK_PREPEND(result, error_message);
2140
1
  } else {
2141
1
    RETURN_NOT_OK(result);
2142
1
  }
2143
1
  return std::move(response);
2144
1
}
yb::Result<yb::master::GetMasterClusterConfigResponsePB> yb::tools::ClusterAdminClient::InvokeRpcNoResponseCheck<yb::master::GetMasterClusterConfigResponsePB, yb::master::GetMasterClusterConfigRequestPB, yb::master::MasterClusterProxy>(yb::Status (yb::master::MasterClusterProxy::*)(yb::master::GetMasterClusterConfigRequestPB const&, yb::master::GetMasterClusterConfigResponsePB*, yb::rpc::RpcController*) const, yb::master::MasterClusterProxy const&, yb::master::GetMasterClusterConfigRequestPB const&, char const*)
Line
Count
Source
2133
34
    const Object& obj, const Request& req, const char* error_message) {
2134
34
  rpc::RpcController rpc;
2135
34
  rpc.set_timeout(timeout_);
2136
34
  Response response;
2137
34
  auto result = (obj.*func)(req, &response, &rpc);
2138
34
  if (error_message) {
2139
34
    RETURN_NOT_OK_PREPEND(result, error_message);
2140
27
  } else {
2141
0
    RETURN_NOT_OK(result);
2142
0
  }
2143
27
  return std::move(response);
2144
34
}
Unexecuted instantiation: yb::Result<yb::master::SplitTabletResponsePB> yb::tools::ClusterAdminClient::InvokeRpcNoResponseCheck<yb::master::SplitTabletResponsePB, yb::master::SplitTabletRequestPB, yb::master::MasterAdminProxy>(yb::Status (yb::master::MasterAdminProxy::*)(yb::master::SplitTabletRequestPB const&, yb::master::SplitTabletResponsePB*, yb::rpc::RpcController*) const, yb::master::MasterAdminProxy const&, yb::master::SplitTabletRequestPB const&, char const*)
Unexecuted instantiation: yb::Result<yb::master::DisableTabletSplittingResponsePB> yb::tools::ClusterAdminClient::InvokeRpcNoResponseCheck<yb::master::DisableTabletSplittingResponsePB, yb::master::DisableTabletSplittingRequestPB, yb::master::MasterAdminProxy>(yb::Status (yb::master::MasterAdminProxy::*)(yb::master::DisableTabletSplittingRequestPB const&, yb::master::DisableTabletSplittingResponsePB*, yb::rpc::RpcController*) const, yb::master::MasterAdminProxy const&, yb::master::DisableTabletSplittingRequestPB const&, char const*)
Unexecuted instantiation: yb::Result<yb::master::IsTabletSplittingCompleteResponsePB> yb::tools::ClusterAdminClient::InvokeRpcNoResponseCheck<yb::master::IsTabletSplittingCompleteResponsePB, yb::master::IsTabletSplittingCompleteRequestPB, yb::master::MasterAdminProxy>(yb::Status (yb::master::MasterAdminProxy::*)(yb::master::IsTabletSplittingCompleteRequestPB const&, yb::master::IsTabletSplittingCompleteResponsePB*, yb::rpc::RpcController*) const, yb::master::MasterAdminProxy const&, yb::master::IsTabletSplittingCompleteRequestPB const&, char const*)
2145
2146
template<class Response, class Request, class Object>
2147
Result<Response> ClusterAdminClient::InvokeRpc(
2148
    Status (Object::*func)(const Request&, Response*, rpc::RpcController*) const,
2149
213
    const Object& obj, const Request& req, const char* error_message) {
2150
213
  return ResponseResult(
VERIFY_RESULT206
(InvokeRpcNoResponseCheck(func, obj, req, error_message)))206
;
2151
213
}
yb::Result<yb::master::ListMastersResponsePB> yb::tools::ClusterAdminClient::InvokeRpc<yb::master::ListMastersResponsePB, yb::master::ListMastersRequestPB, yb::master::MasterClusterProxy>(yb::Status (yb::master::MasterClusterProxy::*)(yb::master::ListMastersRequestPB const&, yb::master::ListMastersResponsePB*, yb::rpc::RpcController*) const, yb::master::MasterClusterProxy const&, yb::master::ListMastersRequestPB const&, char const*)
Line
Count
Source
2149
18
    const Object& obj, const Request& req, const char* error_message) {
2150
18
  return ResponseResult(VERIFY_RESULT(InvokeRpcNoResponseCheck(func, obj, req, error_message)));
2151
18
}
Unexecuted instantiation: yb::Result<yb::consensus::RunLeaderElectionResponsePB> yb::tools::ClusterAdminClient::InvokeRpc<yb::consensus::RunLeaderElectionResponsePB, yb::consensus::RunLeaderElectionRequestPB, yb::consensus::ConsensusServiceProxy>(yb::Status (yb::consensus::ConsensusServiceProxy::*)(yb::consensus::RunLeaderElectionRequestPB const&, yb::consensus::RunLeaderElectionResponsePB*, yb::rpc::RpcController*) const, yb::consensus::ConsensusServiceProxy const&, yb::consensus::RunLeaderElectionRequestPB const&, char const*)
yb::Result<yb::consensus::ChangeConfigResponsePB> yb::tools::ClusterAdminClient::InvokeRpc<yb::consensus::ChangeConfigResponsePB, yb::consensus::ChangeConfigRequestPB, yb::consensus::ConsensusServiceProxy>(yb::Status (yb::consensus::ConsensusServiceProxy::*)(yb::consensus::ChangeConfigRequestPB const&, yb::consensus::ChangeConfigResponsePB*, yb::rpc::RpcController*) const, yb::consensus::ConsensusServiceProxy const&, yb::consensus::ChangeConfigRequestPB const&, char const*)
Line
Count
Source
2149
3
    const Object& obj, const Request& req, const char* error_message) {
2150
3
  return ResponseResult(VERIFY_RESULT(InvokeRpcNoResponseCheck(func, obj, req, error_message)));
2151
3
}
Unexecuted instantiation: yb::Result<yb::master::DumpMasterStateResponsePB> yb::tools::ClusterAdminClient::InvokeRpc<yb::master::DumpMasterStateResponsePB, yb::master::DumpMasterStateRequestPB, yb::master::MasterClusterProxy>(yb::Status (yb::master::MasterClusterProxy::*)(yb::master::DumpMasterStateRequestPB const&, yb::master::DumpMasterStateResponsePB*, yb::rpc::RpcController*) const, yb::master::MasterClusterProxy const&, yb::master::DumpMasterStateRequestPB const&, char const*)
Unexecuted instantiation: yb::Result<yb::master::GetLoadMovePercentResponsePB> yb::tools::ClusterAdminClient::InvokeRpc<yb::master::GetLoadMovePercentResponsePB, yb::master::GetLoadMovePercentRequestPB, yb::master::MasterClusterProxy>(yb::Status (yb::master::MasterClusterProxy::*)(yb::master::GetLoadMovePercentRequestPB const&, yb::master::GetLoadMovePercentResponsePB*, yb::rpc::RpcController*) const, yb::master::MasterClusterProxy const&, yb::master::GetLoadMovePercentRequestPB const&, char const*)
Unexecuted instantiation: yb::Result<yb::master::GetLoadMovePercentResponsePB> yb::tools::ClusterAdminClient::InvokeRpc<yb::master::GetLoadMovePercentResponsePB, yb::master::GetLeaderBlacklistPercentRequestPB, yb::master::MasterClusterProxy>(yb::Status (yb::master::MasterClusterProxy::*)(yb::master::GetLeaderBlacklistPercentRequestPB const&, yb::master::GetLoadMovePercentResponsePB*, yb::rpc::RpcController*) const, yb::master::MasterClusterProxy const&, yb::master::GetLeaderBlacklistPercentRequestPB const&, char const*)
yb::Result<yb::master::GetTabletLocationsResponsePB> yb::tools::ClusterAdminClient::InvokeRpc<yb::master::GetTabletLocationsResponsePB, yb::master::GetTabletLocationsRequestPB, yb::master::MasterClientProxy>(yb::Status (yb::master::MasterClientProxy::*)(yb::master::GetTabletLocationsRequestPB const&, yb::master::GetTabletLocationsResponsePB*, yb::rpc::RpcController*) const, yb::master::MasterClientProxy const&, yb::master::GetTabletLocationsRequestPB const&, char const*)
Line
Count
Source
2149
134
    const Object& obj, const Request& req, const char* error_message) {
2150
134
  return ResponseResult(VERIFY_RESULT(InvokeRpcNoResponseCheck(func, obj, req, error_message)));
2151
134
}
yb::Result<yb::master::ListTabletServersResponsePB> yb::tools::ClusterAdminClient::InvokeRpc<yb::master::ListTabletServersResponsePB, yb::master::ListTabletServersRequestPB, yb::master::MasterClusterProxy>(yb::Status (yb::master::MasterClusterProxy::*)(yb::master::ListTabletServersRequestPB const&, yb::master::ListTabletServersResponsePB*, yb::rpc::RpcController*) const, yb::master::MasterClusterProxy const&, yb::master::ListTabletServersRequestPB const&, char const*)
Line
Count
Source
2149
1
    const Object& obj, const Request& req, const char* error_message) {
2150
1
  return ResponseResult(VERIFY_RESULT(InvokeRpcNoResponseCheck(func, obj, req, error_message)));
2151
1
}
Unexecuted instantiation: yb::Result<yb::tserver::GetLogLocationResponsePB> yb::tools::ClusterAdminClient::InvokeRpc<yb::tserver::GetLogLocationResponsePB, yb::tserver::GetLogLocationRequestPB, yb::tserver::TabletServerServiceProxy>(yb::Status (yb::tserver::TabletServerServiceProxy::*)(yb::tserver::GetLogLocationRequestPB const&, yb::tserver::GetLogLocationResponsePB*, yb::rpc::RpcController*) const, yb::tserver::TabletServerServiceProxy const&, yb::tserver::GetLogLocationRequestPB const&, char const*)
yb::Result<yb::master::LaunchBackfillIndexForTableResponsePB> yb::tools::ClusterAdminClient::InvokeRpc<yb::master::LaunchBackfillIndexForTableResponsePB, yb::master::LaunchBackfillIndexForTableRequestPB, yb::master::MasterDdlProxy>(yb::Status (yb::master::MasterDdlProxy::*)(yb::master::LaunchBackfillIndexForTableRequestPB const&, yb::master::LaunchBackfillIndexForTableResponsePB*, yb::rpc::RpcController*) const, yb::master::MasterDdlProxy const&, yb::master::LaunchBackfillIndexForTableRequestPB const&, char const*)
Line
Count
Source
2149
1
    const Object& obj, const Request& req, const char* error_message) {
2150
1
  return ResponseResult(VERIFY_RESULT(InvokeRpcNoResponseCheck(func, obj, req, error_message)));
2151
1
}
Unexecuted instantiation: yb::Result<yb::tserver::ListTabletsForTabletServerResponsePB> yb::tools::ClusterAdminClient::InvokeRpc<yb::tserver::ListTabletsForTabletServerResponsePB, yb::tserver::ListTabletsForTabletServerRequestPB, yb::tserver::TabletServerServiceProxy>(yb::Status (yb::tserver::TabletServerServiceProxy::*)(yb::tserver::ListTabletsForTabletServerRequestPB const&, yb::tserver::ListTabletsForTabletServerResponsePB*, yb::rpc::RpcController*) const, yb::tserver::TabletServerServiceProxy const&, yb::tserver::ListTabletsForTabletServerRequestPB const&, char const*)
Unexecuted instantiation: yb::Result<yb::master::ChangeLoadBalancerStateResponsePB> yb::tools::ClusterAdminClient::InvokeRpc<yb::master::ChangeLoadBalancerStateResponsePB, yb::master::ChangeLoadBalancerStateRequestPB, yb::master::MasterClusterProxy>(yb::Status (yb::master::MasterClusterProxy::*)(yb::master::ChangeLoadBalancerStateRequestPB const&, yb::master::ChangeLoadBalancerStateResponsePB*, yb::rpc::RpcController*) const, yb::master::MasterClusterProxy const&, yb::master::ChangeLoadBalancerStateRequestPB const&, char const*)
Unexecuted instantiation: yb::Result<yb::master::GetLoadBalancerStateResponsePB> yb::tools::ClusterAdminClient::InvokeRpc<yb::master::GetLoadBalancerStateResponsePB, yb::master::GetLoadBalancerStateRequestPB, yb::master::MasterClusterProxy>(yb::Status (yb::master::MasterClusterProxy::*)(yb::master::GetLoadBalancerStateRequestPB const&, yb::master::GetLoadBalancerStateResponsePB*, yb::rpc::RpcController*) const, yb::master::MasterClusterProxy const&, yb::master::GetLoadBalancerStateRequestPB const&, char const*)
Unexecuted instantiation: yb::Result<yb::master::FlushSysCatalogResponsePB> yb::tools::ClusterAdminClient::InvokeRpc<yb::master::FlushSysCatalogResponsePB, yb::master::FlushSysCatalogRequestPB, yb::master::MasterAdminProxy>(yb::Status (yb::master::MasterAdminProxy::*)(yb::master::FlushSysCatalogRequestPB const&, yb::master::FlushSysCatalogResponsePB*, yb::rpc::RpcController*) const, yb::master::MasterAdminProxy const&, yb::master::FlushSysCatalogRequestPB const&, char const*)
Unexecuted instantiation: yb::Result<yb::master::CompactSysCatalogResponsePB> yb::tools::ClusterAdminClient::InvokeRpc<yb::master::CompactSysCatalogResponsePB, yb::master::CompactSysCatalogRequestPB, yb::master::MasterAdminProxy>(yb::Status (yb::master::MasterAdminProxy::*)(yb::master::CompactSysCatalogRequestPB const&, yb::master::CompactSysCatalogResponsePB*, yb::rpc::RpcController*) const, yb::master::MasterAdminProxy const&, yb::master::CompactSysCatalogRequestPB const&, char const*)
yb::Result<yb::master::ChangeMasterClusterConfigResponsePB> yb::tools::ClusterAdminClient::InvokeRpc<yb::master::ChangeMasterClusterConfigResponsePB, yb::master::ChangeMasterClusterConfigRequestPB, yb::master::MasterClusterProxy>(yb::Status (yb::master::MasterClusterProxy::*)(yb::master::ChangeMasterClusterConfigRequestPB const&, yb::master::ChangeMasterClusterConfigResponsePB*, yb::rpc::RpcController*) const, yb::master::MasterClusterProxy const&, yb::master::ChangeMasterClusterConfigRequestPB const&, char const*)
Line
Count
Source
2149
20
    const Object& obj, const Request& req, const char* error_message) {
2150
20
  return ResponseResult(VERIFY_RESULT(InvokeRpcNoResponseCheck(func, obj, req, error_message)));
2151
20
}
yb::Result<yb::master::IsInitDbDoneResponsePB> yb::tools::ClusterAdminClient::InvokeRpc<yb::master::IsInitDbDoneResponsePB, yb::master::IsInitDbDoneRequestPB, yb::master::MasterAdminProxy>(yb::Status (yb::master::MasterAdminProxy::*)(yb::master::IsInitDbDoneRequestPB const&, yb::master::IsInitDbDoneResponsePB*, yb::rpc::RpcController*) const, yb::master::MasterAdminProxy const&, yb::master::IsInitDbDoneRequestPB const&, char const*)
Line
Count
Source
2149
1
    const Object& obj, const Request& req, const char* error_message) {
2150
1
  return ResponseResult(VERIFY_RESULT(InvokeRpcNoResponseCheck(func, obj, req, error_message)));
2151
1
}
yb::Result<yb::tserver::UpgradeYsqlResponsePB> yb::tools::ClusterAdminClient::InvokeRpc<yb::tserver::UpgradeYsqlResponsePB, yb::tserver::UpgradeYsqlRequestPB, yb::tserver::TabletServerAdminServiceProxy>(yb::Status (yb::tserver::TabletServerAdminServiceProxy::*)(yb::tserver::UpgradeYsqlRequestPB const&, yb::tserver::UpgradeYsqlResponsePB*, yb::rpc::RpcController*) const, yb::tserver::TabletServerAdminServiceProxy const&, yb::tserver::UpgradeYsqlRequestPB const&, char const*)
Line
Count
Source
2149
1
    const Object& obj, const Request& req, const char* error_message) {
2150
1
  return ResponseResult(VERIFY_RESULT(InvokeRpcNoResponseCheck(func, obj, req, error_message)));
2151
1
}
yb::Result<yb::master::GetMasterClusterConfigResponsePB> yb::tools::ClusterAdminClient::InvokeRpc<yb::master::GetMasterClusterConfigResponsePB, yb::master::GetMasterClusterConfigRequestPB, yb::master::MasterClusterProxy>(yb::Status (yb::master::MasterClusterProxy::*)(yb::master::GetMasterClusterConfigRequestPB const&, yb::master::GetMasterClusterConfigResponsePB*, yb::rpc::RpcController*) const, yb::master::MasterClusterProxy const&, yb::master::GetMasterClusterConfigRequestPB const&, char const*)
Line
Count
Source
2149
34
    const Object& obj, const Request& req, const char* error_message) {
2150
34
  return ResponseResult(
VERIFY_RESULT27
(InvokeRpcNoResponseCheck(func, obj, req, error_message)))27
;
2151
34
}
Unexecuted instantiation: yb::Result<yb::master::SplitTabletResponsePB> yb::tools::ClusterAdminClient::InvokeRpc<yb::master::SplitTabletResponsePB, yb::master::SplitTabletRequestPB, yb::master::MasterAdminProxy>(yb::Status (yb::master::MasterAdminProxy::*)(yb::master::SplitTabletRequestPB const&, yb::master::SplitTabletResponsePB*, yb::rpc::RpcController*) const, yb::master::MasterAdminProxy const&, yb::master::SplitTabletRequestPB const&, char const*)
Unexecuted instantiation: yb::Result<yb::master::DisableTabletSplittingResponsePB> yb::tools::ClusterAdminClient::InvokeRpc<yb::master::DisableTabletSplittingResponsePB, yb::master::DisableTabletSplittingRequestPB, yb::master::MasterAdminProxy>(yb::Status (yb::master::MasterAdminProxy::*)(yb::master::DisableTabletSplittingRequestPB const&, yb::master::DisableTabletSplittingResponsePB*, yb::rpc::RpcController*) const, yb::master::MasterAdminProxy const&, yb::master::DisableTabletSplittingRequestPB const&, char const*)
Unexecuted instantiation: yb::Result<yb::master::IsTabletSplittingCompleteResponsePB> yb::tools::ClusterAdminClient::InvokeRpc<yb::master::IsTabletSplittingCompleteResponsePB, yb::master::IsTabletSplittingCompleteRequestPB, yb::master::MasterAdminProxy>(yb::Status (yb::master::MasterAdminProxy::*)(yb::master::IsTabletSplittingCompleteRequestPB const&, yb::master::IsTabletSplittingCompleteResponsePB*, yb::rpc::RpcController*) const, yb::master::MasterAdminProxy const&, yb::master::IsTabletSplittingCompleteRequestPB const&, char const*)
2152
2153
1
Result<const ClusterAdminClient::NamespaceMap&> ClusterAdminClient::GetNamespaceMap() {
2154
1
  if (namespace_map_.empty()) {
2155
1
    auto v = VERIFY_RESULT(yb_client_->ListNamespaces());
2156
3
    for (auto& ns : v) {
2157
3
      auto ns_id = ns.id();
2158
3
      namespace_map_.emplace(std::move(ns_id), std::move(ns));
2159
3
    }
2160
1
  }
2161
1
  return const_cast<const ClusterAdminClient::NamespaceMap&>(namespace_map_);
2162
1
}
2163
2164
19
Result<TableNameResolver> ClusterAdminClient::BuildTableNameResolver() {
2165
19
  return TableNameResolver(VERIFY_RESULT(yb_client_->ListTables()),
2166
19
                           VERIFY_RESULT(yb_client_->ListNamespaces()));
2167
19
}
2168
2169
16
string RightPadToUuidWidth(const string &s) {
2170
16
  return RightPadToWidth(s, kNumCharactersInUuid);
2171
16
}
2172
2173
Result<TypedNamespaceName> ParseNamespaceName(const std::string& full_namespace_name,
2174
0
                                              const YQLDatabase default_if_no_prefix) {
2175
0
  const auto parts = SplitByDot(full_namespace_name);
2176
0
  return ResolveNamespaceName(parts.prefix, parts.value, default_if_no_prefix);
2177
0
}
2178
2179
void AddStringField(
2180
    const char* name, const std::string& value, rapidjson::Value* out,
2181
104
    rapidjson::Value::AllocatorType* allocator) {
2182
104
  rapidjson::Value json_value(value.c_str(), *allocator);
2183
104
  out->AddMember(rapidjson::StringRef(name), json_value, *allocator);
2184
104
}
2185
2186
14
string HybridTimeToString(HybridTime ht) {
2187
14
  return Timestamp(ht.GetPhysicalValueMicros()).ToHumanReadableTime();
2188
14
}
2189
2190
}  // namespace tools
2191
}  // namespace yb