syntax = "proto3";
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, allowing operational work
// to be performed on the cluster (eg. adding nodes, retrieving information
// about a running cluster, etc.).
service Management {
    // GetRegisterTicket retrieves the current RegisterTicket which is required
    // for new nodes to register into the cluster. Presenting this ticket on
    // registration does not automatically grant access to arbitrary node
    // registration. Instead, it is used to guard the API surface of the
    // Register RPC from potential denial of service attacks, and can be
    // regenerated at any time in case it leaks.
    rpc GetRegisterTicket(GetRegisterTicketRequest) returns (GetRegisterTicketResponse) {
        option (metropolis.proto.ext.authorization) = {
            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
        };
    }

    // GetNodes retrieves information about nodes in the cluster. Currently,
    // it returns all available data about all nodes.
    rpc GetNodes(GetNodesRequest) returns (stream Node) {
        option (metropolis.proto.ext.authorization) = {
            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 {
}

message GetRegisterTicketResponse {
    // 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;

    // ca_certificate is the x509 DER encoded CA certificate of the cluster.
    bytes ca_certificate = 2;
}

message GetNodesRequest {
    // filter is a CEL expression used to limit the count of GetNodes results.
    // Each processed node protobuf message is exposed to the filter as
    // "node" variable, while related state and health enum constants are
    // anchored in the root namespace, eg. NODE_STATE_UP, or HEARTBEAT_TIMEOUT.
    // A node is returned each time the expression is evaluated as true. If
    // empty, all nodes are returned.
    string filter = 1;
}

// Node in a Metropolis cluster, streamed by Management.GetNodes. For each node
// in the cluster, this message will be emitted and will contain information
// about that node.
//
// The fields contained are node fields that PERMISSION_READ_CLUSTER_STATUS
// allows access to, ie. 'non-private' fields, ones that might be internal to
// the cluster and possibly considered sensitive information about the
// infrastructure, but whose knowledge does not allow to escalate privileges
// within the cluster.
message Node {
    // Raw Ed25519 public key of this node, which can be used to generate
    // the node's ID. This is always set.
    bytes pubkey = 1;
    // State of the node from the point of view of the cluster. This is
    // always set.
    metropolis.proto.common.NodeState state = 2;
    // Last reported status by the Node, absent if a node hasn't yet reported
    // its status.
    metropolis.proto.common.NodeStatus status = 3;
    // Roles assigned by the cluster. This is always set.
    metropolis.proto.common.NodeRoles roles = 4;

    // Health describes node's health as seen from the cluster perspective.
    enum Health {
      INVALID = 0;
      // UNKNOWN is used whenever there were no heartbeats received from a
      // given node AND too little time has passed since last Curator leader
      // election to know whether the node is actually timing out. UNKNOWN
      // is also returned for nodes which NodeState does not equal
      // NODE_STATE_UP.
      UNKNOWN = 1;
      // HEALTHY describes nodes that have sent a heartbeat recently.
      HEALTHY = 2;
      // HEARTBEAT_TIMEOUT describes nodes that have not sent a heartbeat in
      // the interval specified by curator.HeartbeatTimeout.
      HEARTBEAT_TIMEOUT = 3;
    }
    Health health = 5;
    // heartbeat_timestamp is the duration since the last of the node's
    // heartbeats was received, expressed in nanoseconds. It equals zero if no
    // heartbeats were received.
    int64 heartbeat_timestamp = 6;
}

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 {
}
