blob: 8bf35df2eb0fe5942e9f683e837aec1630933ad5 [file] [log] [blame]
Serge Bazanski63fabd92021-06-17 15:47:22 +02001syntax = "proto3";
2option go_package = "source.monogon.dev/metropolis/node/core/curator/proto/api";
3package metropolis.node.core.curator.proto.api;
4
5import "metropolis/proto/common/common.proto";
Serge Bazanskid7d6e022021-09-01 15:03:06 +02006import "metropolis/proto/ext/authorization.proto";
Serge Bazanski63fabd92021-06-17 15:47:22 +02007
8// The Curator is the main cluster management service of Metropolis.
9//
10// It runs on top of Metropolis and is the main entrypoint for both external
11// and internal services to get cluster state and and get/mutate cluster
12// configuration.
13// It is currently implemented as a leader-elected service running on all nodes
14// that run a consensus server (etcd). Every instance either serves traffic
15// directly (if it is the leader) or passes all RPCs over to the current
16// leader.
17// The curator listens on gRPC over a local UNIX domain socket accessible to the
18// rest of the node code, and on a node's port over TLS with a certificate
19// issued by the Cluster CA.
20//
21// The curator is a privileged service, and performs per-RPC authorization based
22// on the identity of the client:
23// - When serving traffic locally over a UNIX domain socket, the service
24// attaches the identity of this node to the RPCs.
25// - When serving over public gRPC, cluster authentication is required and gRPC
26// client identity will be tied to the RPCs.
27//
28// TODO(q3k): implement and document public Cluster gRPC.
29// TODO(q3k): implement and document cluster auth for nodes and escrowed user
30// keys.
31service Curator {
32 // Watch returns a stream of updates concerning some part of the cluster
33 // managed by the curator, and is the main way in which node code responds
34 // to cluster configuration/state changes.
35 // Once open, the Curator will stream WatchEvents pertinent to the
36 // requested data. At first, the Curator will send WatchEvent(s) describing
37 // the current state of the watched resources, letting the client 'catch
38 // up' with the current cluster state. Then, it will stream WatchEvent(s)
39 // as the pertinent objects change.
40 // There is no way for the client to know whether it is 'up to date' on the
41 // object state, as streamed WatchEvents are not synchronous to internal
42 // state changes within the Curator. Effectively, the view of Watch clients
43 // is eventually consistent with the state of the objects in the Curator.
Serge Bazanskid7d6e022021-09-01 15:03:06 +020044 rpc Watch(WatchRequest) returns (stream WatchEvent) {
45 option (metropolis.proto.ext.authorization) = {
46 need: PERMISSION_READ_CLUSTER_STATUS;
47 };
48 }
Serge Bazanski2893e982021-09-09 13:06:16 +020049 // UpdateNodestatus is called by nodes in the cluster to report their own
50 // status. This status is recorded by the curator and can be retrieved via
51 // Watch.
52 rpc UpdateNodeStatus(UpdateNodeStatusRequest) returns (UpdateNodeStatusResponse) {
53 option (metropolis.proto.ext.authorization) = {
54 need: PERMISSION_UPDATE_NODE_SELF;
55 };
56 }
Serge Bazanski63fabd92021-06-17 15:47:22 +020057}
58
59// Node is the state and configuration of a node in the cluster.
60message Node {
61 // ID of the node. Unique across all nodes. Opaque but human-readable.
62 string id = 1;
63 // Roles that the nodes is supposed to take on.
64 metropolis.proto.common.NodeRoles roles = 2;
Serge Bazanski2893e982021-09-09 13:06:16 +020065 // Last reported status of the node, if available.
66 metropolis.proto.common.NodeStatus status = 3;
Serge Bazanski63fabd92021-06-17 15:47:22 +020067};
68
69// WatchRequest specifies what data the caller is interested in. This influences
70// the contents of WatchEvents.
71message WatchRequest {
72 // The watcher wants information about a single node within the cluster.
73 // This is designed to be used by node-local code that needs to know what
74 // the state of the node and the cluster are for purposes of
75 // starting/stopping services, performing software updates and general node
76 // lifecycle management.
Serge Bazanski80861fd2021-11-02 22:14:06 +010077 //
78 // If the requested node is not yet present in the cluster, the Watch will
79 // block until it is available. If a node is then deleted, a tombstone will
80 // be returned and the call Watch will block forever.
Serge Bazanski63fabd92021-06-17 15:47:22 +020081 message NodeInCluster {
82 // node_id that the watcher is interested in. The curator will, best
83 // effort, stream updates (not necessarily all updates) to this node
84 // within WatchEvents.
85 string node_id = 1;
86 }
Serge Bazanski80861fd2021-11-02 22:14:06 +010087 // The watcher wants information about all the nodes in the cluster. This
88 // is designed to be used by node-local code that needs to know the state
89 // of all the nodes within the cluster, for purposes of building aggregate
90 // views of the cluster, eg. the addresses of all nodes or a list of nodes
91 // fitting some criterion. With time, this call might offer filter
92 // functionality to perform some of this filtering server-side.
93 message NodesInCluster {
94 }
Serge Bazanski63fabd92021-06-17 15:47:22 +020095 oneof kind {
96 NodeInCluster node_in_cluster = 1;
Serge Bazanski80861fd2021-11-02 22:14:06 +010097 NodesInCluster nodes_in_cluster = 2;
Serge Bazanski63fabd92021-06-17 15:47:22 +020098 }
99}
100
101message WatchEvent {
102 // Nodes pertinent to the watch request. The nodes contained might not
103 // contain just the nodes requested in WatchRequest, so the client needs to
104 // filter out anything spurious.
105 repeated Node nodes = 1;
Serge Bazanski80861fd2021-11-02 22:14:06 +0100106 // Node tombstones, a list of node IDs that have been removed from the
107 // cluster since the last sent WatchEvent. For any node in this list, the
108 // watcher should perform logic to remove that node from its current state.
109 message NodeTombstone {
110 string node_id = 1;
111 }
112 repeated NodeTombstone node_tombstones = 3;
113
114 // Progress of the watch stream. This is set for any event which fulfills
115 // some criterion within the context of the watch stream, and is unspecified
116 // otherwise.
117 enum Progress {
118 PROGRESS_UNSPECIFIED = 0;
119 // This event contains the last backlogged data from the watcher: all
120 // data pertinent to the request that is already known to the server
121 // has been returned, and subsequent event receives will block until new
122 // data is available. This will be set on exactly one WatchEvent from
123 // a NodesInCluster RPC, its behaviour is not defined for other Watch
124 // RPCs.
125 PROGRESS_LAST_BACKLOGGED = 1;
126 }
127 Progress progress = 2;
Serge Bazanski63fabd92021-06-17 15:47:22 +0200128}
Serge Bazanski2893e982021-09-09 13:06:16 +0200129
130message UpdateNodeStatusRequest {
131 // node_id is the Metropolis node identity string of the node for which to
132 // set a new status. This currently must be the same node as the one
133 // performing the RPC and is included for safety.
134 string node_id = 1;
135 // status to be set. All fields are overwritten.
136 metropolis.proto.common.NodeStatus status = 2;
137}
138
139message UpdateNodeStatusResponse {
140}