// Copyright 2020 The gRPC 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.

// Local copy of Envoy xDS proto file, used for testing only.

syntax = "proto3";

package envoy.config.cluster.v3;

import "src/proto/grpc/testing/xds/v3/config_source.proto";

// [#protodoc-title: Cluster configuration]

// Configuration for a single upstream cluster.
// [#next-free-field: 48]
message Cluster {
  // Refer to :ref:`service discovery type <arch_overview_service_discovery_types>`
  // for an explanation on each type.
  enum DiscoveryType {
    // Refer to the :ref:`static discovery type<arch_overview_service_discovery_types_static>`
    // for an explanation.
    STATIC = 0;

    // Refer to the :ref:`strict DNS discovery
    // type<arch_overview_service_discovery_types_strict_dns>`
    // for an explanation.
    STRICT_DNS = 1;

    // Refer to the :ref:`logical DNS discovery
    // type<arch_overview_service_discovery_types_logical_dns>`
    // for an explanation.
    LOGICAL_DNS = 2;

    // Refer to the :ref:`service discovery type<arch_overview_service_discovery_types_eds>`
    // for an explanation.
    EDS = 3;

    // Refer to the :ref:`original destination discovery
    // type<arch_overview_service_discovery_types_original_destination>`
    // for an explanation.
    ORIGINAL_DST = 4;
  }

  // Refer to :ref:`load balancer type <arch_overview_load_balancing_types>` architecture
  // overview section for information on each type.
  enum LbPolicy {
    reserved 4;

    reserved "ORIGINAL_DST_LB";

    // Refer to the :ref:`round robin load balancing
    // policy<arch_overview_load_balancing_types_round_robin>`
    // for an explanation.
    ROUND_ROBIN = 0;

    // Refer to the :ref:`least request load balancing
    // policy<arch_overview_load_balancing_types_least_request>`
    // for an explanation.
    LEAST_REQUEST = 1;

    // Refer to the :ref:`ring hash load balancing
    // policy<arch_overview_load_balancing_types_ring_hash>`
    // for an explanation.
    RING_HASH = 2;

    // Refer to the :ref:`random load balancing
    // policy<arch_overview_load_balancing_types_random>`
    // for an explanation.
    RANDOM = 3;

    // Refer to the :ref:`Maglev load balancing policy<arch_overview_load_balancing_types_maglev>`
    // for an explanation.
    MAGLEV = 5;

    // This load balancer type must be specified if the configured cluster provides a cluster
    // specific load balancer. Consult the configured cluster's documentation for whether to set
    // this option or not.
    CLUSTER_PROVIDED = 6;

    // [#not-implemented-hide:] Use the new :ref:`load_balancing_policy
    // <envoy_api_field_config.cluster.v3.Cluster.load_balancing_policy>` field to determine the LB policy.
    // [#next-major-version: In the v3 API, we should consider deprecating the lb_policy field
    // and instead using the new load_balancing_policy field as the one and only mechanism for
    // configuring this.]
    LOAD_BALANCING_POLICY_CONFIG = 7;
  }

  // Only valid when discovery type is EDS.
  message EdsClusterConfig {
    // Configuration for the source of EDS updates for this Cluster.
    core.v3.ConfigSource eds_config = 1;

    // Optional alternative to cluster name to present to EDS. This does not
    // have the same restrictions as cluster name, i.e. it may be arbitrary
    // length.
    string service_name = 2;
  }

  // Supplies the name of the cluster which must be unique across all clusters.
  // The cluster name is used when emitting
  // :ref:`statistics <config_cluster_manager_cluster_stats>` if :ref:`alt_stat_name
  // <envoy_api_field_config.cluster.v3.Cluster.alt_stat_name>` is not provided.
  // Any ``:`` in the cluster name will be converted to ``_`` when emitting statistics.
  string name = 1;

  oneof cluster_discovery_type {
    // The :ref:`service discovery type <arch_overview_service_discovery_types>`
    // to use for resolving the cluster.
    DiscoveryType type = 2;
  }

  // Configuration to use for EDS updates for the Cluster.
  EdsClusterConfig eds_cluster_config = 3;

  // The :ref:`load balancer type <arch_overview_load_balancing_types>` to use
  // when picking a host in the cluster.
  LbPolicy lb_policy = 6;

  // [#not-implemented-hide:]
  // If present, tells the client where to send load reports via LRS. If not present, the
  // client will fall back to a client-side default, which may be either (a) don't send any
  // load reports or (b) send load reports for all clusters to a single default server
  // (which may be configured in the bootstrap file).
  //
  // Note that if multiple clusters point to the same LRS server, the client may choose to
  // create a separate stream for each cluster or it may choose to coalesce the data for
  // multiple clusters onto a single stream. Either way, the client must make sure to send
  // the data for any given cluster on no more than one stream.
  //
  // [#next-major-version: In the v3 API, we should consider restructuring this somehow,
  // maybe by allowing LRS to go on the ADS stream, or maybe by moving some of the negotiation
  // from the LRS stream here.]
  core.v3.ConfigSource lrs_server = 42;
}
