// Copyright 2025 Envoy Project Authors
//
// 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 envoy.admin.v3;

import "envoy/admin/v3/metrics.proto";
import "envoy/config/cluster/v3/circuit_breaker.proto";
import "envoy/config/core/v3/address.proto";
import "envoy/config/core/v3/base.proto";
import "envoy/config/core/v3/health_check.proto";
import "envoy/type/v3/percent.proto";

import "udpa/annotations/status.proto";
import "udpa/annotations/versioning.proto";

option java_package = "io.envoyproxy.envoy.admin.v3";
option java_outer_classname = "ClustersProto";
option java_multiple_files = true;
option go_package = "github.com/envoyproxy/go-control-plane/envoy/admin/v3;adminv3";
option (udpa.annotations.file_status).package_version_status = ACTIVE;

// [#protodoc-title: Clusters]

// Admin endpoint uses this wrapper for ``/clusters`` to display cluster status information.
// See :ref:`/clusters <operations_admin_interface_clusters>` for more information.
message Clusters {
  option (udpa.annotations.versioning).previous_message_type = "envoy.admin.v2alpha.Clusters";

  // Mapping from cluster name to each cluster's status.
  repeated ClusterStatus cluster_statuses = 1;
}

// Details an individual cluster's current status.
// [#next-free-field: 9]
message ClusterStatus {
  option (udpa.annotations.versioning).previous_message_type = "envoy.admin.v2alpha.ClusterStatus";

  // Name of the cluster.
  string name = 1;

  // Denotes whether this cluster was added via API or configured statically.
  bool added_via_api = 2;

  // The success rate threshold used in the last interval.
  //
  // * If :ref:`outlier_detection.split_external_local_origin_errors<envoy_v3_api_field_config.cluster.v3.OutlierDetection.split_external_local_origin_errors>`
  //   is ``false``, all errors: externally and locally generated were used to calculate the threshold.
  // * If :ref:`outlier_detection.split_external_local_origin_errors<envoy_v3_api_field_config.cluster.v3.OutlierDetection.split_external_local_origin_errors>`
  //   is ``true``, only externally generated errors were used to calculate the threshold.
  //
  // The threshold is used to eject hosts based on their success rate. For more information, see the
  // :ref:`Cluster outlier detection <arch_overview_outlier_detection>` documentation.
  //
  // .. note::
  //
  //   This field may be omitted in any of the three following cases:
  //
  //   1. There were not enough hosts with enough request volume to proceed with success rate based outlier ejection.
  //   2. The threshold is computed to be < 0 because a negative value implies that there was no threshold for that
  //      interval.
  //   3. Outlier detection is not enabled for this cluster.
  //
  type.v3.Percent success_rate_ejection_threshold = 3;

  // Mapping from host address to the host's current status.
  repeated HostStatus host_statuses = 4;

  // The success rate threshold used in the last interval when only locally originated failures were
  // taken into account and externally originated errors were treated as success.
  // This field should be interpreted only when
  // :ref:`outlier_detection.split_external_local_origin_errors<envoy_v3_api_field_config.cluster.v3.OutlierDetection.split_external_local_origin_errors>`
  // is ``true``. The threshold is used to eject hosts based on their success rate.
  //
  // For more information, see the :ref:`Cluster outlier detection <arch_overview_outlier_detection>` documentation.
  //
  // .. note::
  //
  //   This field may be omitted in any of the three following cases:
  //
  //   1. There were not enough hosts with enough request volume to proceed with success rate based outlier ejection.
  //   2. The threshold is computed to be < 0 because a negative value implies that there was no threshold for that
  //      interval.
  //   3. Outlier detection is not enabled for this cluster.
  //
  type.v3.Percent local_origin_success_rate_ejection_threshold = 5;

  // :ref:`Circuit breaking <arch_overview_circuit_break>` settings of the cluster.
  config.cluster.v3.CircuitBreakers circuit_breakers = 6;

  // Observability name of the cluster.
  string observability_name = 7;

  // The :ref:`EDS service name <envoy_v3_api_field_config.cluster.v3.Cluster.EdsClusterConfig.service_name>` if the cluster is an EDS cluster.
  string eds_service_name = 8;
}

// Current state of a particular host.
// [#next-free-field: 10]
message HostStatus {
  option (udpa.annotations.versioning).previous_message_type = "envoy.admin.v2alpha.HostStatus";

  // Address of this host.
  config.core.v3.Address address = 1;

  // List of stats specific to this host.
  repeated SimpleMetric stats = 2;

  // The host's current health status.
  HostHealthStatus health_status = 3;

  // The success rate for this host during the last measurement interval.
  //
  // * If :ref:`outlier_detection.split_external_local_origin_errors<envoy_v3_api_field_config.cluster.v3.OutlierDetection.split_external_local_origin_errors>`
  //   is ``false``, all errors: externally and locally generated were used in success rate calculation.
  // * If :ref:`outlier_detection.split_external_local_origin_errors<envoy_v3_api_field_config.cluster.v3.OutlierDetection.split_external_local_origin_errors>`
  //   is ``true``, only externally generated errors were used in success rate calculation.
  //
  // For more information, see the :ref:`Cluster outlier detection <arch_overview_outlier_detection>` documentation.
  //
  // .. note::
  //
  //   The message will be missing if the host didn't receive enough traffic to calculate a reliable success rate, or
  //   if the cluster had too few hosts to apply outlier ejection based on success rate.
  //
  type.v3.Percent success_rate = 4;

  // The host's weight. If not configured, the value defaults to 1.
  uint32 weight = 5;

  // The hostname of the host, if applicable.
  string hostname = 6;

  // The host's priority. If not configured, the value defaults to 0 (highest priority).
  uint32 priority = 7;

  // The success rate for this host during the last interval, considering only locally generated errors. Externally
  // generated errors are treated as successes.
  //
  // This field is only relevant when
  // :ref:`outlier_detection.split_external_local_origin_errors<envoy_v3_api_field_config.cluster.v3.OutlierDetection.split_external_local_origin_errors>`
  // is set to ``true``.
  //
  // For more information, see the :ref:`Cluster outlier detection <arch_overview_outlier_detection>` documentation.
  //
  // .. note::
  //
  //   The message will be missing if the host didn't receive enough traffic to compute a success rate, or if the
  //   cluster didn't have enough hosts to perform outlier ejection based on success rate.
  //
  type.v3.Percent local_origin_success_rate = 8;

  // locality of the host.
  config.core.v3.Locality locality = 9;
}

// Health status for a host.
// [#next-free-field: 9]
message HostHealthStatus {
  option (udpa.annotations.versioning).previous_message_type =
      "envoy.admin.v2alpha.HostHealthStatus";

  // The host is currently failing active health checks.
  bool failed_active_health_check = 1;

  // The host is currently considered an outlier and has been ejected.
  bool failed_outlier_check = 2;

  // The host is currently being marked as degraded through active health checking.
  bool failed_active_degraded_check = 4;

  // The host has been removed from service discovery, but is being stabilized due to active
  // health checking.
  bool pending_dynamic_removal = 5;

  // The host is awaiting first health check.
  bool pending_active_hc = 6;

  // The host should be excluded from panic, spillover, etc. calculations because it was explicitly
  // taken out of rotation via protocol signal and is not meant to be routed to.
  bool excluded_via_immediate_hc_fail = 7;

  // The host failed active health check due to timeout.
  bool active_hc_timeout = 8;

  // Health status as reported by EDS.
  //
  // .. note::
  //
  //   Currently, only ``HEALTHY`` and ``UNHEALTHY`` are supported.
  //
  // [#comment:TODO(mrice32): pipe through remaining EDS health status possibilities.]
  config.core.v3.HealthStatus eds_health_status = 3;
}
