...

Text file src/github.com/linkerd/linkerd2-proxy-api/proto/destination.proto

Documentation: github.com/linkerd/linkerd2-proxy-api/proto

     1syntax = "proto3";
     2
     3package io.linkerd.proxy.destination;
     4
     5option go_package = "github.com/linkerd/linkerd2-proxy-api/go/destination";
     6
     7import "google/protobuf/duration.proto";
     8
     9import "http_types.proto";
    10import "net.proto";
    11
    12/// Destination Service ///
    13//
    14// This is the service discovery API.  Given a destination, this returns a
    15// weighted set of addresses and address metadata.  Can be implemented with DNS
    16// or lookups against other service discovery backends.
    17//
    18// If the service does not exist then the controller must send
    19// `no_endpoints{exists: false}` ASAP when a client subscribes or when the
    20// service stops existing. If the service exists and has endpoints available
    21// then the controller must send `add` that lists all (or at least a large
    22// number) of the endpoints for the service. If and only if the service exists
    23// but does not have any endpoints available then the controller SHOULD send
    24// `no_endpoints{exists: true}` when a client subscribes. In other words, the
    25// `no_endpoints` message must only be sent when there are *no*endpoints for
    26// the service.
    27//
    28// The controller is expected to send an Update every time there is a
    29// change in service discovery.
    30//
    31// The client MUST be prepared to receive messages in any order and the client
    32// MUST be able to cope with the presence or absence of redundant messages.
    33//
    34// `no_endpoints` followed by an `add` is *not* equivalent to just sending the
    35// `add` regardless of the value of the `exists` field in the `no_endpoints`
    36// message. `remove` followed by a `no_endpoints` message is equivalent to
    37// sending just the `no_endpoints` message, and a `remove` that removes the
    38// last endpoint is equivalent to a `no_endpoints{exists: true}` message.
    39//
    40// When the client gets disconnected from the controller and reconnects, the
    41// client may use stale results from its previous subscription until, and only
    42// until, it receives the first message. This is why the controller must send
    43// a message at the start of a subscription. This is also why the controller
    44// must not send a `no_endpoints` message before an `add` message; the client
    45// would clear its cached messages between the time it receives the
    46// `no_endpoints` message and the time it receives the `add` message, which is
    47// not the desired behavior.
    48
    49service Destination {
    50  // Given a destination, return all addresses in that destination as a long-
    51  // running stream of updates.
    52  rpc Get(GetDestination) returns(stream Update) {}
    53
    54  // Given a destination, return that destination's profile and send an update
    55  // whenever it changes.
    56  rpc GetProfile(GetDestination) returns(stream DestinationProfile) {}
    57}
    58
    59message GetDestination {
    60  string scheme = 1;
    61  string path = 2;
    62
    63  // An opaque value that is set at injection-time and sent with destintion
    64  // lookups.
    65  //
    66  // If, for instance, the token encodes a namespace or some locality
    67  // information, the service may alter its results to take this locality into
    68  // account.
    69  string context_token = 3;
    70}
    71
    72message Update {
    73  oneof update {
    74    // A new set of endpoints are available for the service. The set might be
    75    // empty.
    76    WeightedAddrSet add = 1;
    77
    78    // Some endpoints have been removed from the service.
    79    AddrSet remove = 2;
    80
    81    // `no_endpoints{exists: false}` indicates that the service does not exist
    82    // and the client MAY try an alternate service discovery method (e.g. DNS).
    83    //
    84    // `no_endpoints(exists: true)` indicates that the service does exist and
    85    // the client MUST NOT fall back to an alternate service discovery method.
    86    NoEndpoints no_endpoints = 3;
    87  }
    88}
    89
    90message AddrSet { repeated net.TcpAddress addrs = 1; }
    91
    92message WeightedAddrSet {
    93  repeated WeightedAddr addrs = 1;
    94  map<string, string> metric_labels = 2;
    95}
    96
    97message WeightedAddr {
    98  net.TcpAddress addr = 1;
    99  uint32 weight = 3;
   100  map<string, string> metric_labels = 4;
   101  TlsIdentity tls_identity = 5;
   102  ProtocolHint protocol_hint = 6;
   103  AuthorityOverride authority_override = 7;
   104
   105  // The HTTP/2 parameters to use when connecting to the destination, if HTTP/2
   106  // is used. These parameters are used by proxies when the application traffic
   107  // is HTTP/2 or when the H2 ProtocolHint is used to transport HTTP/1
   108  // connections over HTTP/2.
   109  Http2ClientParams http2 = 8;
   110}
   111
   112message TlsIdentity {
   113  reserved 2;
   114  reserved "k8s_pod_identity";
   115
   116  oneof strategy {
   117    DnsLikeIdentity dns_like_identity = 1;
   118    UriLikeIdentity uri_like_identity = 3;
   119  }
   120
   121  // The server name of the endpoint. This is the value that needs to be included
   122  // by clients in the ClientHello SNI extension of the TLS handshake when they
   123  // initiate TLS connections to servers.
   124  DnsLikeIdentity server_name = 4;
   125
   126  // Verify the certificate based on the Kubernetes pod identity.
   127  message DnsLikeIdentity {
   128    // A DNS-like name that encodes workload coordinates.
   129    //
   130    // For example:
   131    //    {name}.{namespace}.{type}.identity.{control-namespace}.{trust-domain...}
   132    string name = 1;
   133  }
   134
   135  // Verify the certificate based on an URI identity.
   136  message UriLikeIdentity {
   137    // A URI name that encodes workload identity.
   138    //
   139    // For example:
   140    //    spiffe://trust-domain/workload-dentifier
   141    string uri = 1;
   142  }
   143}
   144
   145message AuthorityOverride { string authority_override = 1; }
   146
   147message NoEndpoints { bool exists = 1; }
   148
   149// A hint of what protocol the service knows. The default value is
   150// for the `hint` field to be not be set, essentially meaning "unknown".
   151message ProtocolHint {
   152  oneof protocol {
   153    // Hints that the service understands HTTP2 and the proxy's internal
   154    // http2-upgrade mechanism.
   155    H2 h2 = 1;
   156    // Hints that the destination will handle this connection as an opaque TCP
   157    // stream, and (if `opaque_transport` is set) that the proxy should not send
   158    // a `SessionProtocol` as part of its transport header.
   159    Opaque opaque = 3;
   160 }
   161
   162  message H2 {}
   163  message Opaque {}
   164
   165  // When set, indicates that the target supports receiving opaque traffic
   166  // wrapped with the Linkerd connection header on the specified port.
   167  OpaqueTransport opaque_transport = 2;
   168
   169  message OpaqueTransport {
   170    // The target proxy's inbound port.
   171    uint32 inbound_port = 1;
   172  }
   173}
   174
   175// Configures the parameters used to initialize an HTTP/2 connection.
   176message Http2ClientParams {
   177  // Overrides the default client flow control settings.
   178  FlowControl flow_control = 1;
   179
   180  // Enables keep-alive timeouts.
   181  KeepAlive keep_alive = 2;
   182
   183  // Configures Hyper internals.
   184  Internals internals = 3;
   185
   186  message FlowControl {
   187    // Configures the maximum connection-level flow control window size.
   188    uint32 initial_connection_window_size = 1;
   189
   190    // Configures the maximum stream-level flow control window size.
   191    uint32 initial_stream_window_size = 2;
   192
   193    // Enables Hyper's adaptive flow control, ignoring other window settings.
   194    bool adaptive_flow_control = 3;
   195  }
   196
   197  message KeepAlive {
   198    // The time between pings.
   199    google.protobuf.Duration interval = 1;
   200
   201    // The time to wait for a ping response before considering the connection
   202    // dead.
   203    google.protobuf.Duration timeout = 2;
   204
   205    // Whether to send pings when there is no other traffic.
   206    bool while_idle = 3;
   207  }
   208
   209  message Internals {
   210    uint32 max_concurrent_reset_streams = 1;
   211    uint32 max_frame_size = 2;
   212    uint32 max_send_buf_size = 3;
   213  }
   214}
   215
   216message DestinationProfile {
   217  // The fully-qualified service name, if one exists.
   218  //
   219  // When resolving (especially by IP), this field provides the fully-qualified
   220  // name of the resolved service, if one exists. This field does NOT include
   221  // any port information. E.g. a lookup for 10.2.3.4:8080 might have a name
   222  // like `foo.bar.svc.cluster.local`.
   223  //
   224  // Implementations MAY provide names for non-service IP-lookups (e.g., pod or
   225  // node dns names), but this is not required.
   226  //
   227  // If the lookup does not refer to a known named entity, this field MUST be
   228  // left empty.
   229  string fully_qualified_name = 5;
   230
   231  // Indicates that connections on this service address should be handled as
   232  // opaque TCP streams. HTTP routes returned on for such services will be
   233  // ignored.
   234  bool opaque_protocol = 4;
   235
   236  // A list of routes, each with a RequestMatch.  If a request matches
   237  // more than one route, the first match wins.
   238  repeated Route routes = 1;
   239  // The retry budget controls how much additional load the proxy can generate
   240  // as retries. Failured requests on retryable routes will not be retried if
   241  // there is no available budget.
   242  RetryBudget retry_budget = 2;
   243
   244  // If this list is non-empty, requests to this destination should instead be
   245  // split between the destinations in this list.  Each destination should
   246  // receive a portion of the requests proportional to its weight.  If this
   247  // list is empty, requests should be sent to this destination as normal.
   248  repeated WeightedDst dst_overrides = 3;
   249
   250  // If this field is set, it indicates that the target is a known endpoint (and
   251  // not a service address). The values of `fully_qualified_name` and
   252  // `dst_overrides` will be ignored for the purposes of service discovery--
   253  // traffic split and load balancing will be skipped and the single endpoint
   254  // are used.
   255  //
   256  // No endpoint should be set If the target is unknown.
   257  WeightedAddr endpoint = 6;
   258}
   259
   260message Route {
   261  // This route contains requests which match this condition.
   262  RequestMatch condition = 1;
   263  // A list of response classes for this route.  If a response matches
   264  // more than one ResponseClass, the first match wins.  If a response does not
   265  // match any ResponseClasses, it is considered to be a successful response.
   266  repeated ResponseClass response_classes = 2;
   267  // Metric labels to attach to requests and responses that match this route.
   268  map<string, string> metrics_labels = 3;
   269  // If a route is retryable, any failed requests on that route may be retried
   270  // by the proxy.
   271  bool is_retryable = 4;
   272  // After this time has elapsed since receiving the initial request, any
   273  // outstanding request will be cancelled, a timeout error response will be
   274  // returned, and no more retries will be attempted.
   275  google.protobuf.Duration timeout = 5;
   276}
   277
   278message RetryBudget {
   279  // The ratio of additional traffic that may be added by retries.  A
   280  // retry_ratio of 0.1 means that 1 retry may be attempted for every 10 regular
   281  // requests.  A retry_ratio of 1.0 means that 1 retry may be attempted for
   282  // every 1 regular request (in other words, total request load may be doubled
   283  // as a result of retries).
   284  float retry_ratio = 1;
   285  // The proxy may always attempt this number of retries per second, even if it
   286  // would violate the retry_ratio.  This is to allow retries to happen even
   287  // when the request rate is very low.
   288  uint32 min_retries_per_second = 2;
   289  // This duration indicates for how long requests should be considered for the
   290  // purposes of enforcing the retry_ratio.  A higher value considers a larger
   291  // window and therefore allows burstier retries.
   292  google.protobuf.Duration ttl = 3;
   293}
   294
   295message ResponseClass {
   296  // This class contains responses which match this condition.
   297  ResponseMatch condition = 1;
   298  // If responses in this class should be considered failures.  This defaults
   299  // to false (success).
   300  bool is_failure = 2;
   301}
   302
   303message RequestMatch {
   304  message Seq { repeated RequestMatch matches = 1; }
   305
   306  oneof match {
   307    Seq all = 1;
   308    Seq any = 2;
   309    RequestMatch not = 3;
   310
   311    PathMatch path = 4;
   312    http_types.HttpMethod method = 5;
   313    // TODO: match on arbitrary header
   314  }
   315}
   316
   317message PathMatch {
   318  // Match if the request path matches this regex.
   319  string regex = 1;
   320}
   321
   322message ResponseMatch {
   323  message Seq { repeated ResponseMatch matches = 1; }
   324
   325  oneof match {
   326    Seq all = 1;
   327    Seq any = 2;
   328    ResponseMatch not = 3;
   329
   330    HttpStatusRange status = 4;
   331    // TODO: match on arbitrary header or trailer
   332  }
   333}
   334
   335// If either a minimum or maximum is not specified, the range is considered to
   336// be over a discrete value.
   337message HttpStatusRange {
   338  // Minimum matching http status code (inclusive), if specified.
   339  uint32 min = 1;
   340  // Maximum matching http status code (inclusive), if specified.
   341  uint32 max = 2;
   342}
   343
   344message WeightedDst {
   345  // This authority will be used as the `path` in a call to the Destination.Get
   346  // rpc.
   347  string authority = 1;
   348  // The proportion of requests to send to this destination.  This value is
   349  // relative to other weights in the same dst_overrides list.
   350  uint32 weight = 2;
   351}

View as plain text