/*
Copyright 2016 Gravitational, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
syntax = "proto3";

package agentpb;

import "event.proto";

message StatusRequest {
}

message StatusResponse {
  SystemStatus status = 1;
}

message LocalStatusRequest {
}

message LocalStatusResponse {
  NodeStatus status = 1;
}

// LastSeenRequest requests the last seen timestamp for the specified member.
message LastSeenRequest {
  // Name specifies the member's serf name.
  string name = 1;
}

// LastSeenResponse returns the last seen timestamp for the requested member.
message LastSeenResponse {
  // Timestamp specifies the last seen timestamp.
  Timestamp timestamp = 1;
}

// System describes the health status of the cluster.
message SystemStatus {
  enum Type {
    Unknown = 0;
    Running = 1;
    Degraded = 2;
  }
  Type status = 1;
  // Health status of individual nodes.
  repeated NodeStatus nodes = 2;
  Timestamp timestamp = 3;
  // Human-readable status summary.
  string summary = 4;
}

// MembereStatus represents the status of a member of the serf cluster.
message MemberStatus {
  enum Type {
    None = 0;
    Alive = 1;
    Leaving = 2;
    Left = 3;
    Failed = 4;
  }
  string name = 1;
  string addr = 2;
  Type status = 3;
  map<string, string> tags = 4;
}

// NodeStatus represents a result of a health check for a single node.
message NodeStatus {
  string name = 1;

  MemberStatus member_status = 2;

  enum Type {
    Unknown = 0;
    Running = 1;
    Degraded = 2;
  }
  Type status = 3;

  // Probes lists all the health probes collected during the health check.
  repeated Probe probes = 4;
}

// Probe represents the outcome of a single check
message Probe {
  // Checker is the name of the checker that generated the probe
  string checker = 1;
  // Detail is the optional detail specific to the checker
  string detail = 2;
  // Code is the optional code specific to a checker (i.e. HTTP status code)
  string code = 3;
  enum Type {
    Unknown = 0;
    Running = 1;
    Failed = 2;
    Terminated = 3;
  }
  // Severity defines the severity of the probe.
  enum Severity {
    // None severity denotes the severity of a running probe
    None = 0;
    // Critical defines a serious error that requires immediate attention
    Critical = 1;
    // Warning defines a (possibly transient) condition that requires attention
    // but is not critical
    Warning = 2;
  }
  // Status is the result of the probe
  Type status = 4;
  // Error is the probe-specific error message
  string error = 5;
  // CheckerData is a free-form data specific to the checker
  bytes checker_data = 6;
  // Severity is the severity of the probe
  Severity severity = 7;
}

message Timestamp {
  int64 seconds = 1;
  int32 nanoseconds = 2;
}

// TimeRequest is a request to get the node's local time
message TimeRequest {}

// TimeResponse contains the node's local time in UTC
message TimeResponse {
  // Timestamp is the node's local timestamp in UTC
  Timestamp timestamp = 1;
}

// UpdateRequest requests a new event be added to the timeline.
message UpdateRequest {
  // Name specifies the serf name of the requesting node.
  string name = 1;
  // Event specifies the event to be added to the timeline.
  TimelineEvent event = 2;
}

// UpdateResponse indicates a successful update.
message UpdateResponse {}

message TimelineRequest {
  // Params will be used to filter the timeline response.
  map<string, string> params = 1;
}

message TimelineResponse {
  // Events contains a list of timeline events that occurred.
  repeated TimelineEvent events = 1;
}

message TimelineEvent {
  // Timestamp is the node's local timestamp in UTC.
  Timestamp timestamp = 1;
  
  // Data contains event specific data.
  oneof data {
    // ClusterHealthy indicates the cluster is in a healthy state.
    ClusterHealthy clusterHealthy = 2;
    // ClusterDegraded indicates the cluster is in a degraded state.
    ClusterDegraded clusterDegraded = 3;
    // ClusterUpgrade indicates the gravity cluster was upgraded.
    ClusterUpgrade clusterUpgrade = 4;
    // NodeAdded indicates a node was added to the cluster.
    NodeAdded nodeAdded = 5;
    // NodeRemoved indicates a node was removed from the cluster.
    NodeRemoved nodeRemoved = 6;
    //NodeHealthy indicates a node is in a healthy state.
    NodeHealthy nodeHealthy = 7;
    // NodeDegraded indicates a node is in a degraded state.
    NodeDegraded nodeDegraded = 8;
    // ProbeSucceeded indicates a probe has succeeded.
    ProbeSucceeded probeSucceeded = 9;
    // ProbeFailed indicates a probe has failed.
    ProbeFailed probeFailed = 10;
    // LeaderElected indicates a new leader was elected.
    LeaderElected leaderElected = 11;
    // UnknownEvent indicates a unknown event.
    UnknownEvent unknownEvent = 12;
  }
}

// Agent describes the API provided by GRPC agents
service Agent {
  // Status collects the global cluster status
  rpc Status(StatusRequest) returns (StatusResponse) {}
  // LocalStatus collects the local node status
  rpc LocalStatus(LocalStatusRequest) returns (LocalStatusResponse) {}
  // LastSeen requests the last seen timestamp for a specified member
  rpc LastSeen(LastSeenRequest) returns (LastSeenResponse) {}
  // Time requests the node's local time in UTC
  rpc Time(TimeRequest) returns (TimeResponse) {}
  // Timeline collects the status timeline
  rpc Timeline(TimelineRequest) returns (TimelineResponse) {}
  // UpdateTimeline requests a new event be added to the timeline.
  // This RPC is idempotent. Repeated calls with the same event will have no effect.
  rpc UpdateTimeline(UpdateRequest) returns (UpdateResponse) {}
}
