-
Notifications
You must be signed in to change notification settings - Fork 82
Expand file tree
/
Copy pathlib.rs
More file actions
321 lines (293 loc) · 11.5 KB
/
lib.rs
File metadata and controls
321 lines (293 loc) · 11.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
use clickhouse_admin_types_versions::latest;
use dropshot::{
HttpError, HttpResponseCreated, HttpResponseOk,
HttpResponseUpdatedNoContent, Path, Query, RequestContext, TypedBody,
};
use dropshot_api_manager_types::api_versions;
use omicron_common::api::external::Generation;
api_versions!([
// NOTE: These versions will be used across **all three** APIs defined in
// this file. When we need to add the next version, consider carefully if
// these APIs should be split into separate modules or crates with their
// own versions.
// WHEN CHANGING THE API (part 1 of 2):
//
// +- Pick a new semver and define it in the list below. The list MUST
// | remain sorted, which generally means that your version should go at
// | the very top.
// |
// | Duplicate this line, uncomment the *second* copy, update that copy for
// | your new API version, and leave the first copy commented out as an
// | example for the next person.
// v
// (next_int, IDENT), // NOTE: read the note at the start of this macro!
(2, ADD_RETENTION_POLICY_AND_TABLE_USAGE),
(1, INITIAL),
]);
// WHEN CHANGING THE API (part 2 of 2):
//
// The call to `api_versions!` above defines constants of type
// `semver::Version` that you can use in your Dropshot API definition to specify
// the version when a particular endpoint was added or removed. For example, if
// you used:
//
// (2, ADD_FOOBAR)
//
// Then you could use `VERSION_ADD_FOOBAR` as the version in which endpoints
// were added or removed.
/// API interface for our clickhouse-admin-keeper server
///
/// We separate the admin interface for the keeper and server APIs because they
/// are completely disjoint. We only run a clickhouse keeper *or* clickhouse
/// server in a given zone, and therefore each admin api is only useful in one
/// of the zones. Using separate APIs and clients prevents us from having to
/// mark a given endpoint `unimplemented` in the case of it not being usable
/// with one of the zone types.
///
/// Nonetheless, the interfaces themselves are small and serve a similar
/// purpose. Therfore we combine them into the same crate.
#[dropshot::api_description]
pub trait ClickhouseAdminKeeperApi {
type Context;
/// Generate a ClickHouse configuration file for a keeper node on a specified
/// directory and enable the SMF service if not currently enabled.
///
/// Note that we cannot start the keeper service until there is an initial
/// configuration set via this endpoint.
#[endpoint {
method = PUT,
path = "/config",
}]
async fn generate_config_and_enable_svc(
rqctx: RequestContext<Self::Context>,
body: TypedBody<latest::keeper::KeeperConfigurableSettings>,
) -> Result<
HttpResponseCreated<latest::config::GenerateConfigResult>,
HttpError,
>;
/// Retrieve the generation number of a configuration
#[endpoint {
method = GET,
path = "/generation",
}]
async fn generation(
rqctx: RequestContext<Self::Context>,
) -> Result<HttpResponseOk<Generation>, HttpError>;
/// Retrieve a logically grouped information file from a keeper node.
/// This information is used internally by ZooKeeper to manage snapshots
/// and logs for consistency and recovery.
#[endpoint {
method = GET,
path = "/4lw-lgif",
}]
async fn lgif(
rqctx: RequestContext<Self::Context>,
) -> Result<HttpResponseOk<latest::keeper::Lgif>, HttpError>;
/// Retrieve information from ClickHouse virtual node /keeper/config which
/// contains last committed cluster configuration.
#[endpoint {
method = GET,
path = "/raft-config",
}]
async fn raft_config(
rqctx: RequestContext<Self::Context>,
) -> Result<HttpResponseOk<latest::keeper::RaftConfig>, HttpError>;
/// Retrieve configuration information from a keeper node.
#[endpoint {
method = GET,
path = "/4lw-conf",
}]
async fn keeper_conf(
rqctx: RequestContext<Self::Context>,
) -> Result<HttpResponseOk<latest::keeper::KeeperConf>, HttpError>;
/// Retrieve cluster membership information from a keeper node.
#[endpoint {
method = GET,
path = "/cluster-membership",
}]
async fn keeper_cluster_membership(
rqctx: RequestContext<Self::Context>,
) -> Result<
HttpResponseOk<latest::keeper::ClickhouseKeeperClusterMembership>,
HttpError,
>;
}
/// API interface for our clickhouse-admin-server server
///
/// We separate the admin interface for the keeper and server APIs because they
/// are completely disjoint. We only run a clickhouse keeper *or* clickhouse
/// server in a given zone, and therefore each admin api is only useful in one
/// of the zones. Using separate APIs and clients prevents us from having to
/// mark a given endpoint `unimplemented` in the case of it not being usable
/// with one of the zone types.
///
/// Nonetheless, the interfaces themselves are small and serve a similar
/// purpose. Therfore we combine them into the same crate.
#[dropshot::api_description]
pub trait ClickhouseAdminServerApi {
type Context;
/// Generate a ClickHouse configuration file for a server node on a specified
/// directory and enable the SMF service.
#[endpoint {
method = PUT,
path = "/config"
}]
async fn generate_config_and_enable_svc(
rqctx: RequestContext<Self::Context>,
body: TypedBody<latest::server::ServerConfigurableSettings>,
) -> Result<
HttpResponseCreated<latest::config::GenerateConfigResult>,
HttpError,
>;
/// Retrieve the generation number of a configuration
#[endpoint {
method = GET,
path = "/generation",
}]
async fn generation(
rqctx: RequestContext<Self::Context>,
) -> Result<HttpResponseOk<Generation>, HttpError>;
/// Contains information about distributed ddl queries (ON CLUSTER clause)
/// that were executed on a cluster.
#[endpoint {
method = GET,
path = "/distributed-ddl-queue",
}]
async fn distributed_ddl_queue(
rqctx: RequestContext<Self::Context>,
) -> Result<
HttpResponseOk<Vec<latest::server::DistributedDdlQueue>>,
HttpError,
>;
/// Retrieve time series from the system database.
///
/// The value of each data point is the average of all stored data points
/// within the interval.
/// These are internal ClickHouse metrics.
#[endpoint {
method = GET,
path = "/timeseries/{table}/{metric}/avg"
}]
async fn system_timeseries_avg(
rqctx: RequestContext<Self::Context>,
path_params: Path<latest::server::MetricInfoPath>,
query_params: Query<latest::server::TimeSeriesSettingsQuery>,
) -> Result<HttpResponseOk<Vec<latest::server::SystemTimeSeries>>, HttpError>;
/// Idempotently initialize a replicated ClickHouse cluster database.
#[endpoint {
method = PUT,
path = "/init"
}]
async fn init_db(
rqctx: RequestContext<Self::Context>,
) -> Result<HttpResponseUpdatedNoContent, HttpError>;
/// Set the retention policy for timeseries data.
#[endpoint {
method = PUT,
path = "/retention-policy",
versions = VERSION_ADD_RETENTION_POLICY_AND_TABLE_USAGE..,
}]
async fn set_retention_policy(
rqctx: RequestContext<Self::Context>,
policy: TypedBody<latest::retention::RetentionPolicy>,
) -> Result<HttpResponseUpdatedNoContent, HttpError>;
/// Get the retention policy for timeseries data from the database
#[endpoint {
method = GET,
path = "/retention-policy",
versions = VERSION_ADD_RETENTION_POLICY_AND_TABLE_USAGE..,
}]
async fn retention_policy(
rqctx: RequestContext<Self::Context>,
) -> Result<HttpResponseOk<latest::retention::RetentionPolicy>, HttpError>;
/// Return the resource usage of database tables.
#[endpoint {
method = GET,
path = "/usage/database",
versions = VERSION_ADD_RETENTION_POLICY_AND_TABLE_USAGE..,
}]
async fn database_usage(
rqctx: RequestContext<Self::Context>,
) -> Result<HttpResponseOk<latest::usage::DatabaseUsageResult>, HttpError>;
/// Return the resource usage of oximeter timeseries.
#[endpoint {
method = PUT,
path = "/usage/oximeter-timeseries",
versions = VERSION_ADD_RETENTION_POLICY_AND_TABLE_USAGE..,
}]
async fn oximeter_usage(
rqctx: RequestContext<Self::Context>,
) -> Result<HttpResponseOk<latest::usage::OximeterUsageResult>, HttpError>;
}
/// API interface for our clickhouse-admin-single server
///
/// The single-node server is distinct from the both the multi-node servers
/// and its keepers. The sole purpose of this API is to serialize database
/// initialization requests from reconfigurator execution. Multi-node clusters
/// must provide a similar interface via [`ClickhouseAdminServerApi`].
#[dropshot::api_description]
pub trait ClickhouseAdminSingleApi {
type Context;
/// Idempotently initialize a single-node ClickHouse database.
#[endpoint {
method = PUT,
path = "/init"
}]
async fn init_db(
rqctx: RequestContext<Self::Context>,
) -> Result<HttpResponseUpdatedNoContent, HttpError>;
/// Retrieve time series from the system database.
///
/// The value of each data point is the average of all stored data points
/// within the interval.
/// These are internal ClickHouse metrics.
#[endpoint {
method = GET,
path = "/timeseries/{table}/{metric}/avg"
}]
async fn system_timeseries_avg(
rqctx: RequestContext<Self::Context>,
path_params: Path<latest::server::MetricInfoPath>,
query_params: Query<latest::server::TimeSeriesSettingsQuery>,
) -> Result<HttpResponseOk<Vec<latest::server::SystemTimeSeries>>, HttpError>;
/// Set the retention policy for timeseries data.
#[endpoint {
method = PUT,
path = "/retention-policy",
versions = VERSION_ADD_RETENTION_POLICY_AND_TABLE_USAGE..,
}]
async fn set_retention_policy(
rqctx: RequestContext<Self::Context>,
policy: TypedBody<latest::retention::RetentionPolicy>,
) -> Result<HttpResponseUpdatedNoContent, HttpError>;
/// Get the retention policy for timeseries data from the database
#[endpoint {
method = GET,
path = "/retention-policy",
versions = VERSION_ADD_RETENTION_POLICY_AND_TABLE_USAGE..,
}]
async fn retention_policy(
rqctx: RequestContext<Self::Context>,
) -> Result<HttpResponseOk<latest::retention::RetentionPolicy>, HttpError>;
/// Return the resource usage of database tables.
#[endpoint {
method = GET,
path = "/usage/database",
versions = VERSION_ADD_RETENTION_POLICY_AND_TABLE_USAGE..,
}]
async fn database_usage(
rqctx: RequestContext<Self::Context>,
) -> Result<HttpResponseOk<latest::usage::DatabaseUsageResult>, HttpError>;
/// Return the resource usage of oximeter timeseries.
#[endpoint {
method = PUT,
path = "/usage/oximeter-timeseries",
versions = VERSION_ADD_RETENTION_POLICY_AND_TABLE_USAGE..,
}]
async fn oximeter_usage(
rqctx: RequestContext<Self::Context>,
) -> Result<HttpResponseOk<latest::usage::OximeterUsageResult>, HttpError>;
}