// Copyright 2019 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.

// This file contains the xds protocol and its dependency. It can't be used by
// the gRPC library; otherwise there can be duplicate definition problems if
// users depend on both gRPC and Envoy. It can only be used by gRPC tests.
//
// TODO(juanlishen): This file is a hack to avoid a problem we're
// currently having where we can't depend on a proto file in an external
// repo due to bazel limitations.  Once that's fixed, this should be
// removed.  Until this, it should be used in the gRPC tests only, or else it
// will cause a conflict due to the same proto messages being defined in
// multiple files in the same binary.

syntax = "proto3";

package envoy.api.v2;

import "google/protobuf/wrappers.proto";

// Aggregated Discovery Service (ADS) options. This is currently empty, but when
// set in :ref:`ConfigSource <envoy_api_msg_core.ConfigSource>` can be used to
// specify that ADS is to be used.
message AggregatedConfigSource {
}

message SelfConfigSource {
}

message ConfigSource {
  oneof config_source_specifier {
    // When set, ADS will be used to fetch resources. The ADS API configuration
    // source in the bootstrap configuration is used.
    AggregatedConfigSource ads = 3;

    // [#not-implemented-hide:]
    // When set, the client will access the resources from the same server it got the
    // ConfigSource from, although not necessarily from the same stream. This is similar to the
    // :ref:`ads<envoy_api_field.ConfigSource.ads>` field, except that the client may use a
    // different stream to the same server. As a result, this field can be used for things
    // like LRS that cannot be sent on an ADS stream. It can also be used to link from (e.g.)
    // LDS to RDS on the same server without requiring the management server to know its name
    // or required credentials.
    // [#next-major-version: In xDS v3, consider replacing the ads field with this one, since
    // this field can implicitly mean to use the same stream in the case where the ConfigSource
    // is provided via ADS and the specified data can also be obtained via ADS.]
    SelfConfigSource self = 5;
  }
}

enum RoutingPriority {
  DEFAULT = 0;
  HIGH = 1;
}

message CircuitBreakers {
  message Thresholds {
    RoutingPriority priority = 1;
    google.protobuf.UInt32Value max_requests = 4;
  }
  repeated Thresholds thresholds = 1;
}

message ClusterConfig {
  repeated string clusters = 1;
}

message CustomClusterType {
  string name = 1;
  ClusterConfig typed_config = 2;
}

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

  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;

    // The custom cluster type: aggregate cluster in this case.
    CustomClusterType cluster_type = 38;
  }

  // Only valid when discovery type is EDS.
  message EdsClusterConfig {
    // Configuration for the source of EDS updates for this Cluster.
    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;
  }

  // Refer to :ref:`load balancer type <arch_overview_load_balancing_types>` architecture
  // overview section for information on each type.
  enum LbPolicy {
    // 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:`original destination load balancing
    // policy<arch_overview_load_balancing_types_original_destination>`
    // for an explanation.
    //
    // .. attention::
    //
    //   **This load balancing policy is deprecated**. Use CLUSTER_PROVIDED instead.
    //
    ORIGINAL_DST_LB = 4;

    // 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;
  }
  // The :ref:`load balancer type <arch_overview_load_balancing_types>` to use
  // when picking a host in the cluster.
  LbPolicy lb_policy = 6;

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

  CircuitBreakers circuit_breakers = 10;

  ConfigSource lrs_server = 42;
}
