m/n/c/curator: implement Management.ApproveNode

This takes a node from NEW to STANDBY. This is the second-to-last
step requires in a node's regsitration flow.

Change-Id: I88f9c7d2cd824c7d3182195b784a725ec9528d28
Reviewed-on: https://review.monogon.dev/c/monogon/+/442
Reviewed-by: Mateusz Zalega <mateusz@monogon.tech>
diff --git a/metropolis/proto/api/management.proto b/metropolis/proto/api/management.proto
index 63336c8..ba50849 100644
--- a/metropolis/proto/api/management.proto
+++ b/metropolis/proto/api/management.proto
@@ -38,6 +38,28 @@
             need: PERMISSION_READ_CLUSTER_STATUS
         };
     }
+
+    // ApproveNode progresses a node's registration process by changing its state
+    // in the cluster from NEW to STANDBY, if not yet STANDBY. This is required
+    // for the node to fully become part of the cluster (ie. have an UP state),
+    // and is required to be called by a manager manually.
+    //
+    // Managers can find out what nodes require approval by performing
+    // a GetNodes call and filtering for nodes in the NEW state. This call is
+    // idempotent and can be executed multiple times, and is a no-op if the node
+    // is already in the STANDBY or even UP states.
+    //
+    // In the future, approval process will be governed by cluster policy, but
+    // currently any node can be approved by a manager, and the manager is
+    // responsible for performing an out-of-band attestation of the node being/
+    // approved (eg. by verifying that the node that is being approved has the
+    // same public key as what the registering node displays in its startup
+    // logs).
+    rpc ApproveNode(ApproveNodeRequest) returns (ApproveNodeResponse) {
+        option (metropolis.proto.ext.authorization) = {
+            need: PERMISSION_APPROVE_NODE
+        };
+    }
 }
 
 message GetRegisterTicketRequest {
@@ -85,3 +107,13 @@
     // Roles assigned by the cluster. This is always set.
     metropolis.proto.common.NodeRoles roles = 4;
 }
+
+
+message ApproveNodeRequest {
+    // Raw public key of the node being approved, has to correspond to a node
+    // currently in the cluster.
+    bytes pubkey = 1;
+}
+
+message ApproveNodeResponse {
+}
\ No newline at end of file
diff --git a/metropolis/proto/ext/authorization.proto b/metropolis/proto/ext/authorization.proto
index 42beb88..60ad68a 100644
--- a/metropolis/proto/ext/authorization.proto
+++ b/metropolis/proto/ext/authorization.proto
@@ -22,6 +22,7 @@
     PERMISSION_GET_REGISTER_TICKET = 1;
     PERMISSION_READ_CLUSTER_STATUS = 2;
     PERMISSION_UPDATE_NODE_SELF = 3;
+    PERMISSION_APPROVE_NODE = 4;
 }
 
 // Authorization policy for an RPC method. This message/API does not have the