m/n/core: implement GetClusterInfo

This implements Management.GetClusterInfo which is used to retrieve a
ClusterDirectory. This in turn will be used by nodes that wish to
register into a cluster.

This could've been skipped and instead Curator.Watch could've been used.
However, the Curator service is only really (currently) intended to be
used by node-to-node communications. To keep with the current design, we
implement a separate RPC, but we should maybe reconsider if this
separation makes sense.

Change-Id: Ie9d475731f4faafdc51a2aa51a1582ee1a259fd2
Reviewed-on: https://review.monogon.dev/c/monogon/+/340
Reviewed-by: Lorenz Brun <lorenz@monogon.tech>
diff --git a/metropolis/proto/api/BUILD.bazel b/metropolis/proto/api/BUILD.bazel
index ef8885d..9f46fb4 100644
--- a/metropolis/proto/api/BUILD.bazel
+++ b/metropolis/proto/api/BUILD.bazel
@@ -11,7 +11,10 @@
         "management.proto",
     ],
     visibility = ["//visibility:public"],
-    deps = ["//metropolis/proto/ext:ext_proto"],
+    deps = [
+        "//metropolis/proto/common:common_proto",
+        "//metropolis/proto/ext:ext_proto",
+    ],
 )
 
 go_proto_library(
@@ -20,7 +23,10 @@
     importpath = "source.monogon.dev/metropolis/proto/api",
     proto = ":api_proto",
     visibility = ["//visibility:public"],
-    deps = ["//metropolis/proto/ext:go_default_library"],
+    deps = [
+        "//metropolis/proto/common:go_default_library",
+        "//metropolis/proto/ext:go_default_library",
+    ],
 )
 
 go_library(
diff --git a/metropolis/proto/api/management.proto b/metropolis/proto/api/management.proto
index bbd81f8..309fb19 100644
--- a/metropolis/proto/api/management.proto
+++ b/metropolis/proto/api/management.proto
@@ -2,6 +2,7 @@
 package metropolis.proto.api;
 option go_package = "source.monogon.dev/metropolis/proto/api";
 
+import "metropolis/proto/common/common.proto";
 import "metropolis/proto/ext/authorization.proto";
 
 // Management service available to Cluster Managers.
@@ -17,6 +18,15 @@
             need: PERMISSION_GET_REGISTER_TICKET
         };
     }
+    // GetClusterInfo retrieves publicly available summary information about
+    // this cluster, notably data required for nodes to register into a cluster
+    // or join it (other than the Register Ticket, which is gated by an
+    // additional permission).
+    rpc GetClusterInfo(GetClusterInfoRequest) returns (GetClusterInfoResponse) {
+        option (metropolis.proto.ext.authorization) = {
+            need: PERMISSION_READ_CLUSTER_STATUS
+        };
+    }
 }
 
 message GetRegisterTicketRequest {
@@ -26,3 +36,12 @@
     // Opaque bytes that comprise the RegisterTicket.
     bytes ticket = 1;
 }
+
+message GetClusterInfoRequest {
+}
+
+message GetClusterInfoResponse {
+    // cluster_directory contains information about individual nodes in the
+    // cluster that can be used to dial the cluster's services.
+    metropolis.proto.common.ClusterDirectory cluster_directory = 1;
+}