m/n/c/curator: add UpdateStatus

This implements Curator.UpdateStatus, which lets nodes self-report some
status items. Currently this is their external IP address, which is
needed to generate a Cluster Directory which is in turn needed to
register into a cluster.

Change-Id: Ib5464ca78ee3466d9b9f89b7af8b40f613ae8dcc
Reviewed-on: https://review.monogon.dev/c/monogon/+/332
Reviewed-by: Lorenz Brun <lorenz@monogon.tech>
diff --git a/metropolis/node/core/curator/proto/api/api.proto b/metropolis/node/core/curator/proto/api/api.proto
index da3e3c3..ab78ba6 100644
--- a/metropolis/node/core/curator/proto/api/api.proto
+++ b/metropolis/node/core/curator/proto/api/api.proto
@@ -46,6 +46,14 @@
             need: PERMISSION_READ_CLUSTER_STATUS;
         };
     }
+    // UpdateNodestatus is called by nodes in the cluster to report their own
+    // status. This status is recorded by the curator and can be retrieved via
+    // Watch.
+    rpc UpdateNodeStatus(UpdateNodeStatusRequest) returns (UpdateNodeStatusResponse) {
+        option (metropolis.proto.ext.authorization) = {
+            need: PERMISSION_UPDATE_NODE_SELF;
+        };
+    }
 }
 
 // Node is the state and configuration of a node in the cluster.
@@ -54,6 +62,8 @@
     string id = 1;
     // Roles that the nodes is supposed to take on.
     metropolis.proto.common.NodeRoles roles = 2;
+    // Last reported status of the node, if available.
+    metropolis.proto.common.NodeStatus status = 3;
 };
 
 // WatchRequest specifies what data the caller is interested in. This influences
@@ -81,3 +91,15 @@
     // filter out anything spurious.
     repeated Node nodes = 1;
 }
+
+message UpdateNodeStatusRequest {
+    // node_id is the Metropolis node identity string of the node for which to
+    // set a new status. This currently must be the same node as the one
+    // performing the RPC and is included for safety.
+    string node_id = 1;
+    // status to be set. All fields are overwritten.
+    metropolis.proto.common.NodeStatus status = 2;
+}
+
+message UpdateNodeStatusResponse {
+}
diff --git a/metropolis/node/core/curator/proto/private/storage.proto b/metropolis/node/core/curator/proto/private/storage.proto
index 3208cdb..c8b6b79 100644
--- a/metropolis/node/core/curator/proto/private/storage.proto
+++ b/metropolis/node/core/curator/proto/private/storage.proto
@@ -24,6 +24,8 @@
 
     // The node's intended roles when running.
     metropolis.proto.common.NodeRoles roles = 4;
+
+    metropolis.proto.common.NodeStatus status = 5;
 }
 
 // Information about the cluster owner, currently the only Metropolis management