1// Copyright 2019 The gRPC Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// This file contains the xds protocol and its dependency. It can't be used by
16// the gRPC library; otherwise there can be duplicate definition problems if
17// users depend on both gRPC and Envoy. It can only be used by gRPC tests.
18//
19// TODO(juanlishen): This file is a hack to avoid a problem we're
20// currently having where we can't depend on a proto file in an external
21// repo due to bazel limitations.  Once that's fixed, this should be
22// removed.  Until this, it should be used in the gRPC tests only, or else it
23// will cause a conflict due to the same proto messages being defined in
24// multiple files in the same binary.
25
26syntax = "proto3";
27
28package envoy.api.v2;
29
30import "google/protobuf/any.proto";
31import "google/protobuf/struct.proto";
32import "google/protobuf/wrappers.proto";
33
34message Status {
35  // The status code, which should be an enum value of [google.rpc.Code][].
36  int32 code = 1;
37
38  // A developer-facing error message, which should be in English. Any
39  // user-facing error message should be localized and sent in the
40  // [google.rpc.Status.details][] field, or localized by the client.
41  string message = 2;
42
43  // A list of messages that carry the error details.  There is a common set of
44  // message types for APIs to use.
45  repeated google.protobuf.Any details = 3;
46}
47
48///////////////////////////////////////////////////////////////////////////////
49
50// Identifies location of where either Envoy runs or where upstream hosts run.
51message Locality {
52  // Region this :ref:`zone <envoy_api_field_core.Locality.zone>` belongs to.
53  string region = 1;
54
55  // Defines the local service zone where Envoy is running. Though optional, it
56  // should be set if discovery service routing is used and the discovery
57  // service exposes :ref:`zone data <envoy_api_field_endpoint.LocalityLbEndpoints.locality>`,
58  // either in this message or via :option:`--service-zone`. The meaning of zone
59  // is context dependent, e.g. `Availability Zone (AZ)
60  // <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html>`_
61  // on AWS, `Zone <https://cloud.google.com/compute/docs/regions-zones/>`_ on
62  // GCP, etc.
63  string zone = 2;
64
65  // When used for locality of upstream hosts, this field further splits zone
66  // into smaller chunks of sub-zones so they can be load balanced
67  // independently.
68  string sub_zone = 3;
69}
70
71// Identifies a specific Envoy instance. The node identifier is presented to the
72// management server, which may use this identifier to distinguish per Envoy
73// configuration for serving.
74message Node {
75  // An opaque node identifier for the Envoy node. This also provides the local
76  // service node name. It should be set if any of the following features are
77  // used: :ref:`statsd <arch_overview_statistics>`, :ref:`CDS
78  // <config_cluster_manager_cds>`, and :ref:`HTTP tracing
79  // <arch_overview_tracing>`, either in this message or via
80  // :option:`--service-node`.
81  string id = 1;
82
83  // Defines the local service cluster name where Envoy is running. Though
84  // optional, it should be set if any of the following features are used:
85  // :ref:`statsd <arch_overview_statistics>`, :ref:`health check cluster
86  // verification <envoy_api_field_core.HealthCheck.HttpHealthCheck.service_name>`,
87  // :ref:`runtime override directory <envoy_api_msg_config.bootstrap.v2.Runtime>`,
88  // :ref:`user agent addition
89  // <envoy_api_field_config.filter.network.http_connection_manager.v2.HttpConnectionManager.add_user_agent>`,
90  // :ref:`HTTP global rate limiting <config_http_filters_rate_limit>`,
91  // :ref:`CDS <config_cluster_manager_cds>`, and :ref:`HTTP tracing
92  // <arch_overview_tracing>`, either in this message or via
93  // :option:`--service-cluster`.
94  string cluster = 2;
95
96  // Opaque metadata extending the node identifier. Envoy will pass this
97  // directly to the management server.
98  google.protobuf.Struct metadata = 3;
99
100  // Locality specifying where the Envoy instance is running.
101  Locality locality = 4;
102
103  // This is motivated by informing a management server during canary which
104  // version of Envoy is being tested in a heterogeneous fleet. This will be set
105  // by Envoy in management server RPCs.
106  string build_version = 5 [deprecated = true];
107
108  // Free-form string that identifies the entity requesting config.
109  // E.g. "envoy" or "grpc"
110  string user_agent_name = 6;
111
112  oneof user_agent_version_type {
113    // Free-form string that identifies the version of the entity requesting config.
114    // E.g. "1.12.2" or "abcd1234", or "SpecialEnvoyBuild"
115    string user_agent_version = 7;
116  }
117
118  // Client feature support list. These are well known features described
119  // in the Envoy API repository for a given major version of an API. Client features
120  // use reverse DNS naming scheme, for example `com.acme.feature`.
121  // See :ref:`the list of features <client_features>` that xDS client may
122  // support.
123  repeated string client_features = 10;
124}
125
126///////////////////////////////////////////////////////////////////////////////
127
128// A DiscoveryRequest requests a set of versioned resources of the same type for
129// a given Envoy node on some API.
130message DiscoveryRequest {
131  // The version_info provided in the request messages will be the version_info
132  // received with the most recent successfully processed response or empty on
133  // the first request. It is expected that no new request is sent after a
134  // response is received until the Envoy instance is ready to ACK/NACK the new
135  // configuration. ACK/NACK takes place by returning the new API config version
136  // as applied or the previous API config version respectively. Each type_url
137  // (see below) has an independent version associated with it.
138  string version_info = 1;
139
140  // The node making the request.
141  Node node = 2;
142
143  // List of resources to subscribe to, e.g. list of cluster names or a route
144  // configuration name. If this is empty, all resources for the API are
145  // returned. LDS/CDS expect empty resource_names, since this is global
146  // discovery for the Envoy instance. The LDS and CDS responses will then imply
147  // a number of resources that need to be fetched via EDS/RDS, which will be
148  // explicitly enumerated in resource_names.
149  repeated string resource_names = 3;
150
151  // Type of the resource that is being requested, e.g.
152  // "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment". This is implicit
153  // in requests made via singleton xDS APIs such as CDS, LDS, etc. but is
154  // required for ADS.
155  string type_url = 4;
156
157  // nonce corresponding to DiscoveryResponse being ACK/NACKed. See above
158  // discussion on version_info and the DiscoveryResponse nonce comment. This
159  // may be empty if no nonce is available, e.g. at startup or for non-stream
160  // xDS implementations.
161  string response_nonce = 5;
162
163  // This is populated when the previous :ref:`DiscoveryResponse <envoy_api_msg_DiscoveryResponse>`
164  // failed to update configuration. The *message* field in *error_details* provides the Envoy
165  // internal exception related to the failure. It is only intended for consumption during manual
166  // debugging, the string provided is not guaranteed to be stable across Envoy versions.
167  Status error_detail = 6;
168}
169
170message DiscoveryResponse {
171  // The version of the response data.
172  string version_info = 1;
173
174  // The response resources. These resources are typed and depend on the API being called.
175  repeated google.protobuf.Any resources = 2;
176
177  // [#not-implemented-hide:]
178  // Canary is used to support two Envoy command line flags:
179  //
180  // * --terminate-on-canary-transition-failure. When set, Envoy is able to
181  //   terminate if it detects that configuration is stuck at canary. Consider
182  //   this example sequence of updates:
183  //   - Management server applies a canary config successfully.
184  //   - Management server rolls back to a production config.
185  //   - Envoy rejects the new production config.
186  //   Since there is no sensible way to continue receiving configuration
187  //   updates, Envoy will then terminate and apply production config from a
188  //   clean slate.
189  // * --dry-run-canary. When set, a canary response will never be applied, only
190  //   validated via a dry run.
191  bool canary = 3;
192
193  // Type URL for resources. This must be consistent with the type_url in the
194  // Any messages for resources if resources is non-empty. This effectively
195  // identifies the xDS API when muxing over ADS.
196  string type_url = 4;
197
198  // For gRPC based subscriptions, the nonce provides a way to explicitly ack a
199  // specific DiscoveryResponse in a following DiscoveryRequest. Additional
200  // messages may have been sent by Envoy to the management server for the
201  // previous version on the stream prior to this DiscoveryResponse, that were
202  // unprocessed at response send time. The nonce allows the management server
203  // to ignore any further DiscoveryRequests for the previous version until a
204  // DiscoveryRequest bearing the nonce. The nonce is optional and is not
205  // required for non-stream based xDS implementations.
206  string nonce = 5;
207}
208
209///////////////////////////////////////////////////////////////////////////////
210
211message Pipe {
212  // Unix Domain Socket path. On Linux, paths starting with '@' will use the
213  // abstract namespace. The starting '@' is replaced by a null byte by Envoy.
214  // Paths starting with '@' will result in an error in environments other than
215  // Linux.
216  string path = 1;
217}
218
219message SocketAddress {
220  enum Protocol {
221    TCP = 0;
222    // [#not-implemented-hide:]
223    UDP = 1;
224  }
225  Protocol protocol = 1;
226  // The address for this socket. :ref:`Listeners <config_listeners>` will bind
227  // to the address. An empty address is not allowed. Specify ``0.0.0.0`` or ``::``
228  // to bind to any address. [#comment:TODO(zuercher) reinstate when implemented:
229  // It is possible to distinguish a Listener address via the prefix/suffix matching
230  // in :ref:`FilterChainMatch <envoy_api_msg_listener.FilterChainMatch>`.] When used
231  // within an upstream :ref:`BindConfig <envoy_api_msg_core.BindConfig>`, the address
232  // controls the source address of outbound connections. For :ref:`clusters
233  // <envoy_api_msg_Cluster>`, the cluster type determines whether the
234  // address must be an IP (*STATIC* or *EDS* clusters) or a hostname resolved by DNS
235  // (*STRICT_DNS* or *LOGICAL_DNS* clusters). Address resolution can be customized
236  // via :ref:`resolver_name <envoy_api_field_core.SocketAddress.resolver_name>`.
237  string address = 2;
238  oneof port_specifier {
239    uint32 port_value = 3;
240    // This is only valid if :ref:`resolver_name
241    // <envoy_api_field_core.SocketAddress.resolver_name>` is specified below and the
242    // named resolver is capable of named port resolution.
243    string named_port = 4;
244  }
245  // The name of the resolver. This must have been registered with Envoy. If this is
246  // empty, a context dependent default applies. If address is a hostname this
247  // should be set for resolution other than DNS. If the address is a concrete
248  // IP address, no resolution will occur.
249  string resolver_name = 5;
250
251  // When binding to an IPv6 address above, this enables `IPv4 compatibity
252  // <https://tools.ietf.org/html/rfc3493#page-11>`_. Binding to ``::`` will
253  // allow both IPv4 and IPv6 connections, with peer IPv4 addresses mapped into
254  // IPv6 space as ``::FFFF:<IPv4-address>``.
255  bool ipv4_compat = 6;
256}
257
258// Addresses specify either a logical or physical address and port, which are
259// used to tell Envoy where to bind/listen, connect to upstream and find
260// management servers.
261message Address {
262  oneof address {
263
264    SocketAddress socket_address = 1;
265    Pipe pipe = 2;
266  }
267}
268
269///////////////////////////////////////////////////////////////////////////////
270
271message Metadata {
272  // Key is the reverse DNS filter name, e.g. com.acme.widget. The envoy.*
273  // namespace is reserved for Envoy's built-in filters.
274  map<string, google.protobuf.Struct> filter_metadata = 1;
275}
276
277///////////////////////////////////////////////////////////////////////////////
278
279// Endpoint health status.
280enum HealthStatus {
281  // The health status is not known. This is interpreted by Envoy as *HEALTHY*.
282  UNKNOWN = 0;
283
284  // Healthy.
285  HEALTHY = 1;
286
287  // Unhealthy.
288  UNHEALTHY = 2;
289
290  // Connection draining in progress. E.g.,
291  // `<https://aws.amazon.com/blogs/aws/elb-connection-draining-remove-instances-from-service-with-care/>`_
292  // or
293  // `<https://cloud.google.com/compute/docs/load-balancing/enabling-connection-draining>`_.
294  // This is interpreted by Envoy as *UNHEALTHY*.
295  DRAINING = 3;
296
297  // Health check timed out. This is part of HDS and is interpreted by Envoy as
298  // *UNHEALTHY*.
299  TIMEOUT = 4;
300}
301
302///////////////////////////////////////////////////////////////////////////////
303
304// Upstream host identifier.
305message Endpoint {
306  // The upstream host address.
307  //
308  // .. attention::
309  //
310  //   The form of host address depends on the given cluster type. For STATIC or EDS,
311  //   it is expected to be a direct IP address (or something resolvable by the
312  //   specified :ref:`resolver <envoy_api_field_core.SocketAddress.resolver_name>`
313  //   in the Address). For LOGICAL or STRICT DNS, it is expected to be hostname,
314  //   and will be resolved via DNS.
315  Address address = 1;
316
317  // The optional health check configuration.
318  message HealthCheckConfig {
319    // Optional alternative health check port value.
320    //
321    // By default the health check address port of an upstream host is the same
322    // as the host's serving address port. This provides an alternative health
323    // check port. Setting this with a non-zero value allows an upstream host
324    // to have different health check address port.
325    uint32 port_value = 1;
326  }
327
328  // The optional health check configuration is used as configuration for the
329  // health checker to contact the health checked host.
330  //
331  // .. attention::
332  //
333  //   This takes into effect only for upstream clusters with
334  //   :ref:`active health checking <arch_overview_health_checking>` enabled.
335  HealthCheckConfig health_check_config = 2;
336}
337
338// An Endpoint that Envoy can route traffic to.
339message LbEndpoint {
340  // Upstream host identifier
341  Endpoint endpoint = 1;
342
343  // Optional health status when known and supplied by EDS server.
344  HealthStatus health_status = 2;
345
346  // The endpoint metadata specifies values that may be used by the load
347  // balancer to select endpoints in a cluster for a given request. The filter
348  // name should be specified as *envoy.lb*. An example boolean key-value pair
349  // is *canary*, providing the optional canary status of the upstream host.
350  // This may be matched against in a route's
351  // :ref:`RouteAction <envoy_api_msg_route.RouteAction>` metadata_match field
352  // to subset the endpoints considered in cluster load balancing.
353  Metadata metadata = 3;
354
355  // The optional load balancing weight of the upstream host, in the range 1 -
356  // 128. Envoy uses the load balancing weight in some of the built in load
357  // balancers. The load balancing weight for an endpoint is divided by the sum
358  // of the weights of all endpoints in the endpoint's locality to produce a
359  // percentage of traffic for the endpoint. This percentage is then further
360  // weighted by the endpoint's locality's load balancing weight from
361  // LocalityLbEndpoints. If unspecified, each host is presumed to have equal
362  // weight in a locality.
363  //
364  // .. attention::
365  //
366  //   The limit of 128 is somewhat arbitrary, but is applied due to performance
367  //   concerns with the current implementation and can be removed when
368  //   `this issue <https://github.com/envoyproxy/envoy/issues/1285>`_ is fixed.
369  google.protobuf.UInt32Value load_balancing_weight = 4;
370}
371
372// A group of endpoints belonging to a Locality.
373// One can have multiple LocalityLbEndpoints for a locality, but this is
374// generally only done if the different groups need to have different load
375// balancing weights or different priorities.
376message LocalityLbEndpoints {
377  // Identifies location of where the upstream hosts run.
378  Locality locality = 1;
379
380  // The group of endpoints belonging to the locality specified.
381  repeated LbEndpoint lb_endpoints = 2;
382
383  // Optional: Per priority/region/zone/sub_zone weight - range 1-128. The load
384  // balancing weight for a locality is divided by the sum of the weights of all
385  // localities  at the same priority level to produce the effective percentage
386  // of traffic for the locality.
387  //
388  // Locality weights are only considered when :ref:`locality weighted load
389  // balancing <arch_overview_load_balancing_locality_weighted_lb>` is
390  // configured. These weights are ignored otherwise. If no weights are
391  // specificed when locality weighted load balancing is enabled, the cluster is
392  // assumed to have a weight of 1.
393  //
394  // .. attention::
395  //
396  //   The limit of 128 is somewhat arbitrary, but is applied due to performance
397  //   concerns with the current implementation and can be removed when
398  //   `this issue <https://github.com/envoyproxy/envoy/issues/1285>`_ is fixed.
399  google.protobuf.UInt32Value load_balancing_weight = 3;
400
401  // Optional: the priority for this LocalityLbEndpoints. If unspecified this will
402  // default to the highest priority (0).
403  //
404  // Under usual circumstances, Envoy will only select endpoints for the highest
405  // priority (0). In the event all endpoints for a particular priority are
406  // unavailable/unhealthy, Envoy will fail over to selecting endpoints for the
407  // next highest priority group.
408  //
409  // Priorities should range from 0 (highest) to N (lowest) without skipping.
410  uint32 priority = 5;
411}
412
413///////////////////////////////////////////////////////////////////////////////
414
415message FractionalPercent {
416  // Specifies the numerator. Defaults to 0.
417  uint32 numerator = 1;
418
419  // Fraction percentages support several fixed denominator values.
420  enum DenominatorType {
421    // 100.
422    //
423    // **Example**: 1/100 = 1%.
424    HUNDRED = 0;
425
426    // 10,000.
427    //
428    // **Example**: 1/10000 = 0.01%.
429    TEN_THOUSAND = 1;
430
431    // 1,000,000.
432    //
433    // **Example**: 1/1000000 = 0.0001%.
434    MILLION = 2;
435  }
436
437  // Specifies the denominator. If the denominator specified is less than the numerator, the final
438  // fractional percentage is capped at 1 (100%).
439  DenominatorType denominator = 2;
440}
441
442///////////////////////////////////////////////////////////////////////////////
443
444// [#protodoc-title: EDS]
445// Endpoint discovery :ref:`architecture overview <arch_overview_service_discovery_types_eds>`
446service EndpointDiscoveryService {
447  // The resource_names field in DiscoveryRequest specifies a list of clusters
448  // to subscribe to updates for.
449  rpc StreamEndpoints(stream DiscoveryRequest) returns (stream DiscoveryResponse) {
450  }
451}
452
453// Each route from RDS will map to a single cluster or traffic split across
454// clusters using weights expressed in the RDS WeightedCluster.
455//
456// With EDS, each cluster is treated independently from a LB perspective, with
457// LB taking place between the Localities within a cluster and at a finer
458// granularity between the hosts within a locality. For a given cluster, the
459// effective weight of a host is its load_balancing_weight multiplied by the
460// load_balancing_weight of its Locality.
461message ClusterLoadAssignment {
462  // Name of the cluster. This will be the :ref:`service_name
463  // <envoy_api_field_Cluster.EdsClusterConfig.service_name>` value if specified
464  // in the cluster :ref:`EdsClusterConfig
465  // <envoy_api_msg_Cluster.EdsClusterConfig>`.
466  string cluster_name = 1;
467
468  // List of endpoints to load balance to.
469  repeated LocalityLbEndpoints endpoints = 2;
470
471  // Load balancing policy settings.
472  message Policy {
473    reserved 1;
474
475    message DropOverload {
476      // Identifier for the policy specifying the drop.
477      string category = 1;
478
479      // Percentage of traffic that should be dropped for the category.
480      FractionalPercent drop_percentage = 2;
481    }
482    // Action to trim the overall incoming traffic to protect the upstream
483    // hosts. This action allows protection in case the hosts are unable to
484    // recover from an outage, or unable to autoscale or unable to handle
485    // incoming traffic volume for any reason.
486    //
487    // At the client each category is applied one after the other to generate
488    // the 'actual' drop percentage on all outgoing traffic. For example:
489    //
490    // .. code-block:: json
491    //
492    //  { "drop_overloads": [
493    //      { "category": "throttle", "drop_percentage": 60 }
494    //      { "category": "lb", "drop_percentage": 50 }
495    //  ]}
496    //
497    // The actual drop percentages applied to the traffic at the clients will be
498    //    "throttle"_drop = 60%
499    //    "lb"_drop = 20%  // 50% of the remaining 'actual' load, which is 40%.
500    //    actual_outgoing_load = 20% // remaining after applying all categories.
501    repeated DropOverload drop_overloads = 2;
502
503    // Priority levels and localities are considered overprovisioned with this
504    // factor (in percentage). This means that we don't consider a priority
505    // level or locality unhealthy until the percentage of healthy hosts
506    // multiplied by the overprovisioning factor drops below 100.
507    // With the default value 140(1.4), Envoy doesn't consider a priority level
508    // or a locality unhealthy until their percentage of healthy hosts drops
509    // below 72%.
510    // Read more at :ref:`priority levels <arch_overview_load_balancing_priority_levels>` and
511    // :ref:`localities <arch_overview_load_balancing_locality_weighted_lb>`.
512    google.protobuf.UInt32Value overprovisioning_factor = 3;
513  }
514
515  // Load balancing policy settings.
516  Policy policy = 4;
517}
518