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