1syntax = "proto3";
2package etcdserverpb;
3
4import "gogoproto/gogo.proto";
5import "etcd/storage/storagepb/kv.proto";
6
7option (gogoproto.marshaler_all) = true;
8option (gogoproto.unmarshaler_all) = true;
9
10service KV {
11  // Range gets the keys in the range from the store.
12  rpc Range(RangeRequest) returns (RangeResponse) {}
13
14  // Put puts the given key into the store.
15  // A put request increases the revision of the store,
16  // and generates one event in the event history.
17  rpc Put(PutRequest) returns (PutResponse) {}
18
19  // Delete deletes the given range from the store.
20  // A delete request increase the revision of the store,
21  // and generates one event in the event history.
22  rpc DeleteRange(DeleteRangeRequest) returns (DeleteRangeResponse) {}
23
24  // Txn processes all the requests in one transaction.
25  // A txn request increases the revision of the store,
26  // and generates events with the same revision in the event history.
27  // It is not allowed to modify the same key several times within one txn.
28  rpc Txn(TxnRequest) returns (TxnResponse) {}
29
30  // Compact compacts the event history in etcd. User should compact the
31  // event history periodically, or it will grow infinitely.
32  rpc Compact(CompactionRequest) returns (CompactionResponse) {}
33
34  // Hash returns the hash of local KV state for consistency checking purpose.
35  // This is designed for testing purpose. Do not use this in production when there
36  // are ongoing transactions.
37  rpc Hash(HashRequest) returns (HashResponse) {}
38}
39
40service Watch {
41  // Watch watches the events happening or happened. Both input and output
42  // are stream. One watch rpc can watch for multiple keys or prefixs and
43  // get a stream of events. The whole events history can be watched unless
44  // compacted.
45  rpc Watch(stream WatchRequest) returns (stream WatchResponse) {}
46}
47
48service Lease {
49  // LeaseCreate creates a lease. A lease has a TTL. The lease will expire if the
50  // server does not receive a keepAlive within TTL from the lease holder.
51  // All keys attached to the lease will be expired and deleted if the lease expires.
52  // The key expiration generates an event in event history.
53  rpc LeaseCreate(LeaseCreateRequest) returns (LeaseCreateResponse) {}
54
55  // LeaseRevoke revokes a lease. All the key attached to the lease will be expired and deleted.
56  rpc LeaseRevoke(LeaseRevokeRequest) returns (LeaseRevokeResponse) {}
57
58  // KeepAlive keeps the lease alive.
59  rpc LeaseKeepAlive(stream LeaseKeepAliveRequest) returns (stream LeaseKeepAliveResponse) {}
60
61  // TODO(xiangli) List all existing Leases?
62  // TODO(xiangli) Get details information (expirations, leased keys, etc.) of a lease?
63}
64
65service Cluster {
66  // MemberAdd adds a member into the cluster.
67  rpc MemberAdd(MemberAddRequest) returns (MemberAddResponse) {}
68
69  // MemberRemove removes an existing member from the cluster.
70  rpc MemberRemove(MemberRemoveRequest) returns (MemberRemoveResponse) {}
71
72  // MemberUpdate updates the member configuration.
73  rpc MemberUpdate(MemberUpdateRequest) returns (MemberUpdateResponse) {}
74
75  // MemberList lists all the members in the cluster.
76  rpc MemberList(MemberListRequest) returns (MemberListResponse) {}
77}
78
79service Maintenance {
80  // TODO: move Hash from kv to Maintenance
81  rpc Defragment(DefragmentRequest) returns (DefragmentResponse) {}
82}
83
84service Auth {
85  // AuthEnable enables authentication.
86  rpc AuthEnable(AuthEnableRequest) returns (AuthEnableResponse) {}
87
88  // AuthDisable disables authentication.
89  rpc AuthDisable(AuthDisableRequest) returns (AuthDisableResponse) {}
90
91  // Authenticate processes authenticate request.
92  rpc Authenticate(AuthenticateRequest) returns (AuthenticateResponse) {}
93
94  // UserAdd adds a new user.
95  rpc UserAdd(UserAddRequest) returns (UserAddResponse) {}
96
97  // UserGet gets a detailed information of a user or lists entire users.
98  rpc UserGet(UserGetRequest) returns (UserGetResponse) {}
99
100  // UserDelete deletes a specified user.
101  rpc UserDelete(UserDeleteRequest) returns (UserDeleteResponse) {}
102
103  // UserChangePassword changes password of a specified user.
104  rpc UserChangePassword(UserChangePasswordRequest) returns (UserChangePasswordResponse) {}
105
106  // UserGrant grants a role to a specified user.
107  rpc UserGrant(UserGrantRequest) returns (UserGrantResponse) {}
108
109  // UserRevoke revokes a role of specified user.
110  rpc UserRevoke(UserRevokeRequest) returns (UserRevokeResponse) {}
111
112  // RoleAdd adds a new role.
113  rpc RoleAdd(RoleAddRequest) returns (RoleAddResponse) {}
114
115  // RoleGet gets a detailed information of a role or lists entire roles.
116  rpc RoleGet(RoleGetRequest) returns (RoleGetResponse) {}
117
118  // RoleDelete deletes a specified role.
119  rpc RoleDelete(RoleDeleteRequest) returns (RoleDeleteResponse) {}
120
121  // RoleGrant grants a permission of a specified key or range to a specified role.
122  rpc RoleGrant(RoleGrantRequest) returns (RoleGrantResponse) {}
123
124  // RoleRevoke revokes a key or range permission of a specified role.
125  rpc RoleRevoke(RoleRevokeRequest) returns (RoleRevokeResponse) {}
126}
127
128message ResponseHeader {
129  uint64 cluster_id = 1;
130  uint64 member_id = 2;
131  // revision of the store when the request was applied.
132  int64 revision = 3;
133  // term of raft when the request was applied.
134  uint64 raft_term = 4;
135}
136
137message RangeRequest {
138  enum SortOrder {
139	NONE = 0; // default, no sorting
140	ASCEND = 1; // lowest target value first
141	DESCEND = 2; // highest target value first
142  }
143  enum SortTarget {
144	KEY = 0;
145	VERSION = 1;
146	CREATE = 2;
147	MOD = 3;
148	VALUE = 4;
149  }
150
151  // if the range_end is not given, the request returns the key.
152  bytes key = 1;
153  // if the range_end is given, it gets the keys in range [key, range_end)
154  // if range_end is nonempty, otherwise it returns all keys >= key.
155  bytes range_end = 2;
156  // limit the number of keys returned.
157  int64 limit = 3;
158  // range over the store at the given revision.
159  // if revision is less or equal to zero, range over the newest store.
160  // if the revision has been compacted, ErrCompaction will be returned in
161  // response.
162  int64 revision = 4;
163
164  // sort_order is the requested order for returned the results
165  SortOrder sort_order = 5;
166
167  // sort_target is the kv field to use for sorting
168  SortTarget sort_target = 6;
169
170  // range request is linearizable by default. Linearizable requests has a higher
171  // latency and lower throughput than serializable request.
172  // To reduce latency, serializable can be set. If serializable is set, range request
173  // will be serializable, but not linearizable with other requests.
174  // Serializable range can be served locally without waiting for other nodes in the cluster.
175  bool serializable = 7;
176}
177
178message RangeResponse {
179  ResponseHeader header = 1;
180  repeated storagepb.KeyValue kvs = 2;
181  // more indicates if there are more keys to return in the requested range.
182  bool more = 3;
183}
184
185message PutRequest {
186  bytes key = 1;
187  bytes value = 2;
188  int64 lease = 3;
189}
190
191message PutResponse {
192  ResponseHeader header = 1;
193}
194
195message DeleteRangeRequest {
196  // if the range_end is not given, the request deletes the key.
197  bytes key = 1;
198  // if the range_end is given, it deletes the keys in range [key, range_end).
199  bytes range_end = 2;
200}
201
202message DeleteRangeResponse {
203  ResponseHeader header = 1;
204  // Deleted is the number of keys that got deleted.
205  int64 deleted = 2;
206}
207
208message RequestUnion {
209  oneof request {
210    RangeRequest request_range = 1;
211    PutRequest request_put = 2;
212    DeleteRangeRequest request_delete_range = 3;
213  }
214}
215
216message ResponseUnion {
217  oneof response {
218    RangeResponse response_range = 1;
219    PutResponse response_put = 2;
220    DeleteRangeResponse response_delete_range = 3;
221  }
222}
223
224message Compare {
225  enum CompareResult {
226    EQUAL = 0;
227    GREATER = 1;
228    LESS = 2;
229  }
230  enum CompareTarget {
231    VERSION = 0;
232    CREATE = 1;
233    MOD = 2;
234    VALUE= 3;
235  }
236  CompareResult result = 1;
237  CompareTarget target = 2;
238  // key path
239  bytes key = 3;
240  oneof target_union {
241    // version of the given key
242    int64 version = 4;
243    // create revision of the given key
244    int64 create_revision = 5;
245    // last modified revision of the given key
246    int64 mod_revision = 6;
247    // value of the given key
248    bytes value = 7;
249  }
250}
251
252// If the comparisons succeed, then the success requests will be processed in order,
253// and the response will contain their respective responses in order.
254// If the comparisons fail, then the failure requests will be processed in order,
255// and the response will contain their respective responses in order.
256
257// From google paxosdb paper:
258// Our implementation hinges around a powerful primitive which we call MultiOp. All other database
259// operations except for iteration are implemented as a single call to MultiOp. A MultiOp is applied atomically
260// and consists of three components:
261// 1. A list of tests called guard. Each test in guard checks a single entry in the database. It may check
262// for the absence or presence of a value, or compare with a given value. Two different tests in the guard
263// may apply to the same or different entries in the database. All tests in the guard are applied and
264// MultiOp returns the results. If all tests are true, MultiOp executes t op (see item 2 below), otherwise
265// it executes f op (see item 3 below).
266// 2. A list of database operations called t op. Each operation in the list is either an insert, delete, or
267// lookup operation, and applies to a single database entry. Two different operations in the list may apply
268// to the same or different entries in the database. These operations are executed
269// if guard evaluates to
270// true.
271// 3. A list of database operations called f op. Like t op, but executed if guard evaluates to false.
272message TxnRequest {
273  repeated Compare compare = 1;
274  repeated RequestUnion success = 2;
275  repeated RequestUnion failure = 3;
276}
277
278message TxnResponse {
279  ResponseHeader header = 1;
280  bool succeeded = 2;
281  repeated ResponseUnion responses = 3;
282}
283
284// Compaction compacts the kv store upto the given revision (including).
285// It removes the old versions of a key. It keeps the newest version of
286// the key even if its latest modification revision is smaller than the given
287// revision.
288message CompactionRequest {
289  int64 revision = 1;
290}
291
292message CompactionResponse {
293  ResponseHeader header = 1;
294}
295
296message HashRequest {
297}
298
299message HashResponse {
300  ResponseHeader header = 1;
301  uint32 hash = 2;
302}
303
304message WatchRequest {
305  oneof request_union {
306    WatchCreateRequest create_request = 1;
307    WatchCancelRequest cancel_request = 2;
308  }
309}
310
311message WatchCreateRequest {
312  // the key to be watched
313  bytes key = 1;
314  // if the range_end is given, keys in [key, range_end) are watched
315  // NOTE: only range_end == prefixEnd(key) is accepted now
316  bytes range_end = 2;
317  // start_revision is an optional revision (including) to watch from. No start_revision is "now".
318  int64 start_revision = 3;
319  // if progress_notify is set, etcd server sends WatchResponse with empty events to the
320  // created watcher when there are no recent events. It is useful when clients want always to be
321  // able to recover a disconnected watcher from a recent known revision.
322  // etcdsever can decide how long it should send a notification based on current load.
323  bool progress_notify = 4;
324}
325
326message WatchCancelRequest {
327  int64 watch_id = 1;
328}
329
330message WatchResponse {
331  ResponseHeader header = 1;
332  // watch_id is the ID of the watching the response sent to.
333  int64 watch_id = 2;
334  // If the response is for a create watch request, created is set to true.
335  // Client should record the watch_id and prepare for receiving events for
336  // that watching from the same stream.
337  // All events sent to the created watching will attach with the same watch_id.
338  bool created = 3;
339  // If the response is for a cancel watch request, cancel is set to true.
340  // No further events will be sent to the canceled watching.
341  bool canceled = 4;
342  // CompactRevision is set to the minimum index if a watching tries to watch
343  // at a compacted index.
344  //
345  // This happens when creating a watching at a compacted revision or the watching cannot
346  // catch up with the progress of the KV.
347  //
348  // Client should treat the watching as canceled and should not try to create any
349  // watching with same start_revision again.
350  int64 compact_revision  = 5;
351
352  repeated storagepb.Event events = 11;
353}
354
355message LeaseCreateRequest {
356  // advisory ttl in seconds
357  int64 TTL = 1;
358  // requested ID to create; 0 lets lessor choose
359  int64 ID = 2;
360}
361
362message LeaseCreateResponse {
363  ResponseHeader header = 1;
364  int64 ID = 2;
365  // server decided ttl in second
366  int64 TTL = 3;
367  string error = 4;
368}
369
370message LeaseRevokeRequest {
371  int64 ID = 1;
372}
373
374message LeaseRevokeResponse {
375  ResponseHeader header = 1;
376}
377
378message LeaseKeepAliveRequest {
379  int64 ID = 1;
380}
381
382message LeaseKeepAliveResponse {
383  ResponseHeader header = 1;
384  int64 ID = 2;
385  int64 TTL = 3;
386}
387
388message Member {
389  uint64 ID = 1;
390  // If the member is not started, name will be an empty string.
391  string name = 2;
392  bool IsLeader = 3;
393  repeated string peerURLs = 4;
394  // If the member is not started, client_URLs will be an zero length
395  // string array.
396  repeated string clientURLs = 5;
397}
398
399message MemberAddRequest {
400  repeated string peerURLs = 1;
401}
402
403message MemberAddResponse {
404  ResponseHeader header = 1;
405  Member member = 2;
406}
407
408message MemberRemoveRequest {
409  uint64 ID = 1;
410}
411
412message MemberRemoveResponse {
413  ResponseHeader header = 1;
414}
415
416message MemberUpdateRequest {
417  uint64 ID = 1;
418  repeated string peerURLs = 2;
419}
420
421message MemberUpdateResponse{
422  ResponseHeader header = 1;
423}
424
425message MemberListRequest {
426}
427
428message MemberListResponse {
429  ResponseHeader header = 1;
430  repeated Member members = 2;
431}
432
433message DefragmentRequest {
434
435}
436
437message DefragmentResponse {
438  ResponseHeader header = 1;
439}
440
441message AuthEnableRequest {
442}
443
444message AuthDisableRequest {
445}
446
447message AuthenticateRequest {
448}
449
450message UserAddRequest {
451}
452
453message UserGetRequest {
454}
455
456message UserDeleteRequest {
457}
458
459message UserChangePasswordRequest {
460}
461
462message UserGrantRequest {
463}
464
465message UserRevokeRequest {
466}
467
468message RoleAddRequest {
469}
470
471message RoleGetRequest {
472}
473
474message RoleDeleteRequest {
475}
476
477message RoleGrantRequest {
478}
479
480message RoleRevokeRequest {
481}
482
483message AuthEnableResponse {
484  ResponseHeader header = 1;
485}
486
487message AuthDisableResponse {
488  ResponseHeader header = 1;
489}
490
491message AuthenticateResponse {
492  ResponseHeader header = 1;
493}
494
495message UserAddResponse {
496  ResponseHeader header = 1;
497}
498
499message UserGetResponse {
500  ResponseHeader header = 1;
501}
502
503message UserDeleteResponse {
504  ResponseHeader header = 1;
505}
506
507message UserChangePasswordResponse {
508  ResponseHeader header = 1;
509}
510
511message UserGrantResponse {
512  ResponseHeader header = 1;
513}
514
515message UserRevokeResponse {
516  ResponseHeader header = 1;
517}
518
519message RoleAddResponse {
520  ResponseHeader header = 1;
521}
522
523message RoleGetResponse {
524  ResponseHeader header = 1;
525}
526
527message RoleDeleteResponse {
528  ResponseHeader header = 1;
529}
530
531message RoleGrantResponse {
532  ResponseHeader header = 1;
533}
534
535message RoleRevokeResponse {
536  ResponseHeader header = 1;
537}
538