sigs.k8s.io/gateway-api@v1.0.0/geps/gep-1016.md (about)

     1  # GEP-1016: GRPCRoute
     2  
     3  * Issue: [#1016](https://github.com/kubernetes-sigs/gateway-api/issues/1016)
     4  * Status: Experimental
     5  
     6  > **Note**: This GEP is exempt from the [Probationary Period][expprob] rules of
     7  > our GEP overview as it existed before those rules did, and so it has been
     8  > explicitly grandfathered in.
     9  
    10  [expprob]:https://gateway-api.sigs.k8s.io/geps/overview/#probationary-period
    11  
    12  ## Goal
    13  
    14  Add an idiomatic GRPCRoute for routing gRPC traffic.
    15  
    16  ## Non-Goals
    17  
    18  While certain gRPC implementations support multiple transports and multiple
    19  interface definition languages (IDLs), this proposal limits itself to
    20  [HTTP/2](https://developers.google.com/web/fundamentals/performance/http2) as
    21  the transport and [Protocol Buffers](https://developers.google.com/protocol-buffers)
    22  as the IDL, which makes up the vast majority of gRPC traffic in the wild.
    23  
    24  ## Introduction
    25  
    26  While it would be possible to support gRPC via custom, out-of-tree CRDs, in the long run, this would
    27  lead to a fragmented ecosystem.
    28  
    29  gRPC is a [popular RPC framework adopted widely across the industry](https://grpc.io/about/#whos-using-grpc-and-why).
    30  The protocol is used pervasively within the Kubernetes project itself as the basis for
    31  many interfaces, including:
    32  
    33  - [the CSI](https://github.com/container-storage-interface/spec/blob/5b0d4540158a260cb3347ef1c87ede8600afb9bf/spec.md),
    34  - [the CRI](https://github.com/kubernetes/cri-api/blob/49fe8b135f4556ea603b1b49470f8365b62f808e/README.md),
    35  - [the device plugin framework](https://kubernetes.io/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins/)
    36  
    37  Given gRPC's importance in the application-layer networking space and to
    38  the Kubernetes project in particular, we must ensure that the gRPC control plane
    39  configuration landscape does not Balkanize.
    40  
    41  ### Encapsulated Network Protocols
    42  
    43  It is theoretically possible to route gRPC traffic using only `HTTPRoute`
    44  resources, but there are several serious problems with forcing gRPC users to route traffic at
    45  the level of HTTP. This is why we propose a new resource.
    46  
    47  In setting this precedent, we must also introduce a coherent policy for _when_
    48  to introduce a custom `Route` resource for an encapsulated protocol for which a
    49  lower layer protocol already exists. We propose the following criteria for such
    50  an addition.
    51  
    52  - Users of the encapsulated protocol would miss out on significant conventional features from their ecosystem if forced to route at a lower layer.
    53  - Users of the enapsulated protocol would experience a degraded user experience if forced to route at a lower layer.
    54  - The encapsulated protocol has a significant user base, particularly in the Kubernetes community.
    55  
    56  gRPC meets _all_ of these criteria and is therefore, we contend, a strong
    57  candidate for inclusion in the Gateway API.
    58  
    59  #### HTTP/2 Cleartext
    60  
    61  gRPC allows HTTP/2 cleartext communication (H2C). This is conventionally deployed for
    62  testing. Many control plane implementations do not support this by default and
    63  would require special configuration to work properly.
    64  
    65  #### Content-Based Routing
    66  
    67  While not included in the scope of this initial GEP, a common use case cited for
    68  routing gRPC is payload-aware routing. That is, routing rules which determine a
    69  backend based on the contents of the protocol buffer payload.
    70  
    71  #### User Experience
    72  
    73  The user experience would also degrade significantly if forced to route at the level of HTTP.
    74  
    75  - Encoding services and methods as URIs (an implementation detail of gRPC)
    76  - The [Transfer Encoding header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Transfer-Encoding) for trailers
    77  - Many features supported by HTTP/2 but not by gRPC, such as
    78    - Query parameters
    79    - Methods besides `POST`
    80    - [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)
    81  
    82  
    83  #### Proxyless Service Mesh
    84  
    85  The gRPC library supports proxyless service mesh, a system by which routing
    86  configuration is received and acted upon not by an in-line proxy or sidecar
    87  proxy but by the client itself. Eventually, `GRPCRoute` in the Gateway API
    88  should support this feature.  However, to date, there are no HTTP client
    89  libraries capable of participating in a proxyless service mesh.
    90  
    91  --- 
    92  
    93  ### Cross Serving
    94  
    95  Occasionally, gRPC users will place gRPC services on the same hostname/port
    96  combination as HTTP services. For example, `foo.com:443/v1` might serve
    97  REST+JSON while `foo.com:443/com.foo.WidgetService/` serves gRPC. Such an
    98  arrangement in the Gateway API poses complex technical challenges. How are
    99  GRPCRoutes to be reconciled with HTTPRoutes? And how should individual
   100  implementations accomplisht this?
   101  
   102  After a long look at the implementations with which the author is familiar, it
   103  was deemed technically infeasible. Furthermore, after surveying the gRPC
   104  community, this was found to be a niche use case to begin with.
   105  
   106  In any case, users wishing to accomplish this always have the option of using
   107  `HTTPRoute` resources to achieve this use case, at the cost of a degraded user
   108  experience.
   109  
   110  If at some point in the future, demand for this use case increases and we have
   111  reason to believe that the feasibility of implementation has improved, this
   112  would be a backward compatible change.
   113  
   114  As such, implementations that support GRPCRoute must enforce uniqueness of
   115  hostnames between `GRPCRoute`s and `HTTPRoute`s. If a route (A) of type `HTTPRoute` or
   116  `GRPCRoute` is attached to a Listener and that listener already has another Route (B) of
   117  the other type attached and the intersection of the hostnames of A and B is
   118  non-empty, then the implementation must reject Route A. That is, the
   119  implementation must raise an 'Accepted' condition with a status of 'False' in
   120  the corresponding RouteParentStatus.
   121  
   122  
   123  ## API
   124  
   125  The API deviates from `HTTPRoute` where it results in a better UX for gRPC
   126  users, while mirroring it in all other cases.
   127  
   128  ### Example `GRPCRoute`
   129  
   130  ```yaml
   131  kind: GRPCRoute
   132  apiVersion: gateway.networking.k8s.io/v1alpha2
   133  metadata:
   134    name: foo-grpcroute
   135  spec:
   136    parentRefs:
   137    - name: my-gateway
   138    hostnames:
   139    - foo.com
   140    - bar.com
   141    rules:
   142    - matches:
   143        method:
   144          service: helloworld.Greeter
   145          method:  SayHello
   146        headers:
   147        - type: Exact
   148          name: magic
   149          value: foo
   150  
   151      filters:
   152      - type: RequestHeaderModifierFilter
   153        add:
   154          - name: my-header
   155            value: foo
   156  
   157      - type: RequestMirrorPolicyFilter
   158        destination:
   159          backendRef:
   160            name: mirror-svc
   161  
   162      backendRefs:
   163      - name: foo-v1
   164        weight: 90
   165      - name: foo-v2
   166        weight: 10
   167  ```
   168  
   169  #### Method Matchers
   170  
   171  It's been pointed out that the `method` field above stutters. That is, in order
   172  to specify a method matcher, one must type the string `method` twice in a row.
   173  This is an artifact of less-than-clear nomenclature within gRPC. There
   174  _are_ alternatives for the naming here, but none of them would actually be an
   175  improvement on the stutter. Consider the following URI:
   176  
   177  `/foo.bar.v1.WidgetService/GetWidget`
   178  
   179  - `/foo.bar.v1.WidgetService/GetWidget` is called the method or, less commonly, the _full_ method. 
   180  - `foo.bar.v1.WidgetService` is called the service or, less commonly, the _full_ service (since `WidgetService` can reasonably be called the service)]
   181  - `GetWidget` is called the method.
   182  
   183  These terms _could_ be added in, but these names are found almost exclusively
   184  within the various gRPC implementations. And inconsistently across those
   185  implementations.
   186  
   187  Therefore, we opt for the stutter over any of the longer names outlined above.
   188  
   189  #### Matcher Types
   190  
   191  `GRPCRoute` method matchers admits two types: `Exact` and `RegularExpression`.
   192  If not specified, the match will be treated as type `Exact`. Method matchers
   193  will act _as if_ a URI match had been used. A full matrix of equivalent behavior
   194  is provided below:
   195  
   196  ##### Type Exact
   197  
   198  |Service|Method|URI Matcher|
   199  |----------|----------|-----------|
   200  |Specified|Specified|Exact `/${SERVICE}/${METHOD}`|
   201  |Specified|Unspecified|Prefix `/${SERVICE}/`|
   202  |Unspecified|Specified|Suffix `/${METHOD}/` or Regex `/.+/${METHOD}`|
   203  |Unspecified|Unspecified|Not allowed|
   204  
   205  ##### Type RegularExpression
   206  
   207  |Service|Method|URI Matcher|
   208  |----------|----------|-----------|
   209  |Specified|Specified|Regex `/${SERVICE}/${METHOD}`|
   210  |Specified|Unspecified|Regex `/${SERVICE}/.+`|
   211  |Unspecified|Specified|Regex `/.+/${METHOD}`|
   212  |Unspecified|Unspecified|Prefix `/`|
   213  
   214  ##### Method specified but not Service
   215  
   216  In the table above, `Service` unspecified and `Method` specified with type Exact
   217  is listed as being equivalent to a path matcher with type suffix or type regex.
   218  We imagine that many GRPCRoute implementations will be done using translation to
   219  `HTTPRoute`s. `HTTPRoute` does not support a Suffix matcher and its Regex
   220  matcher is specified as "Implementation-specific" support. In order to accommodate
   221  `GRPCRoute` implementations built on top of `HTTPRoute` implementations without
   222  regex support, we list this particular case as having implementation-specific 
   223  support within the context of `GRPCRoute`.
   224  
   225  #### Transport
   226  
   227  No new `ProtocolType` will be added. While gRPC _does_ have some special
   228  HTTP usage (HTTP/2 cleartext and HTTP/2 without an upgrade from HTTP/1.1),
   229  `GRPCRoute` will be used in conjunction with the existing `HTTP` and `HTTPS`
   230  ProtocolTypes.
   231  
   232  Implementations supporting `GRPCRoute` with the `HTTPS` `ProtocolType` must
   233  accept HTTP/2 connections without an [initial upgrade from HTTP/1.1](https://datatracker.ietf.org/doc/html/rfc7230#section-6.7). If the
   234  implementation does not support this, then it should raise a "Detached"
   235  condition for the affected listener with a reason of "UnsupportedProtocol"
   236  
   237  Implementations supporting `GRPCRoute` with the `HTTP` `ProtocolType` must
   238  support cleartext HTTP/2 connections without an [initial upgrade from HTTP/1.1](https://datatracker.ietf.org/doc/html/rfc7230#section-6.7). If the implementation does not support this, then it
   239  should raise a "Detached" condition for the affected listener with a reason of
   240  "UnsupportedProtocol"
   241  
   242  
   243  ### Structs
   244  
   245  {% raw%}
   246  ```go
   247  // +genclient
   248  // +kubebuilder:object:root=true
   249  // +kubebuilder:resource:categories=gateway-api
   250  // +kubebuilder:subresource:status
   251  // +kubebuilder:storageversion
   252  // +kubebuilder:printcolumn:name="Hostnames",type=string,JSONPath=`.spec.hostnames`
   253  // +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
   254  
   255  // GRPCRoute provides a way to route gRPC requests. This includes the capability
   256  // to match requests by hostname, gRPC service, gRPC method, or HTTP/2 header. Filters can be
   257  // used to specify additional processing steps. Backends specify where matching
   258  // requests should be routed.
   259  //
   260  // Implementations supporting `GRPCRoute` with the `HTTPS` `ProtocolType` must
   261  // accept HTTP/2 connections without an initial upgrade from HTTP/1.1. If the
   262  // implementation does not support this, then it should raise a "Detached"
   263  // condition for the affected listener with a reason of "UnsupportedProtocol"
   264  //
   265  // Implementations supporting `GRPCRoute` with the `HTTP` `ProtocolType` must
   266  // support cleartext HTTP/2 without an initial upgrade from HTTP/1.1. If the
   267  // implementation does not support this, then it should raise a "Detached"
   268  // condition for the affected listener with a reason of "UnsupportedProtocol"
   269  //
   270  // Support: Extended
   271  type GRPCRoute struct {
   272  	metav1.TypeMeta   `json:",inline"`
   273  	metav1.ObjectMeta `json:"metadata,omitempty"`
   274  
   275  	// Spec defines the desired state of GRPCRoute.
   276  	Spec GRPCRouteSpec `json:"spec,omitempty"`
   277  
   278  	// Status defines the current state of GRPCRoute.
   279  	Status GRPCRouteStatus `json:"status,omitempty"`
   280  }
   281  
   282  // GRPCRouteStatus defines the observed state of GRPCRoute.
   283  type GRPCRouteStatus struct {
   284  	RouteStatus `json:",inline"`
   285  }
   286  
   287  // GRPCRouteSpec defines the desired state of GRPCRoute
   288  type GRPCRouteSpec struct {
   289  	CommonRouteSpec `json:",inline"`
   290  
   291  	// Hostnames defines a set of hostname that should match against the GRPC
   292  	// Host header to select a GRPCRoute to process the request. This matches
   293  	// the RFC 1123 definition of a hostname with 2 notable exceptions:
   294  	//
   295  	// 1. IPs are not allowed.
   296  	// 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard
   297  	//    label must appear by itself as the first label.
   298  	//
   299  	// If a hostname is specified by both the Listener and GRPCRoute, there
   300  	// must be at least one intersecting hostname for the GRPCRoute to be
   301  	// attached to the Listener. For example:
   302  	//
   303  	// * A Listener with `test.example.com` as the hostname matches GRPCRoutes
   304  	//   that have either not specified any hostnames, or have specified at
   305  	//   least one of `test.example.com` or `*.example.com`.
   306  	// * A Listener with `*.example.com` as the hostname matches GRPCRoutes
   307  	//   that have either not specified any hostnames or have specified at least
   308  	//   one hostname that matches the Listener hostname. For example,
   309  	//   `test.example.com` and `*.example.com` would both match. On the other
   310  	//   hand, `example.com` and `test.example.net` would not match.
   311  	//
   312  	// If both the Listener and GRPCRoute have specified hostnames, any
   313  	// GRPCRoute hostnames that do not match the Listener hostname MUST be
   314  	// ignored. For example, if a Listener specified `*.example.com`, and the
   315  	// GRPCRoute specified `test.example.com` and `test.example.net`,
   316  	// `test.example.net` must not be considered for a match.
   317  	//
   318  	// If both the Listener and GRPCRoute have specified hostnames, and none
   319  	// match with the criteria above, then the GRPCRoute is not accepted. The
   320  	// implementation must raise an 'Accepted' Condition with a status of
   321  	// `False` in the corresponding RouteParentStatus.
   322  	//
   323  	// If a Route (A) of type HTTPRoute or GRPCRoute is attached to a
   324  	// Listener and that listener already has another Route (B) of the other
   325  	// type attached and the intersection of the hostnames of A and B is
   326  	// non-empty, then the implementation must reject Route A. That is, the
   327  	// implementation must raise an 'Accepted' condition with a status of
   328  	// 'False' in the corresponding RouteParentStatus.
   329  	//
   330  	// Support: Core
   331  	//
   332  	// +optional
   333  	// +kubebuilder:validation:MaxItems=16
   334  	Hostnames []Hostname `json:"hostnames,omitempty"`
   335  
   336  	// Rules are a list of GRPC matchers, filters and actions.
   337          // 
   338  	// +optional
   339  	// +kubebuilder:validation:MaxItems=16
   340  	// +kubebuilder:default={{matches: {{method: {type: "Exact"}}}}}
   341  	Rules []GRPCRouteRule `json:"rules,omitempty"`
   342  }
   343  
   344  // GRPCRouteRule defines semantics for matching an gRPC request based on
   345  // conditions (matches), processing it (filters), and forwarding the request to
   346  // an API object (backendRefs).
   347  type GRPCRouteRule struct {
   348  	// Matches define conditions used for matching the rule against incoming
   349  	// gRPC requests. Each match is independent, i.e. this rule will be matched
   350  	// if **any** one of the matches is satisfied.
   351  	//
   352  	// For example, take the following matches configuration:
   353  	//
   354  	// ```
   355  	// matches:
   356  	// - method:
   357  	//     service: foo.bar
   358  	//   headers:
   359  	//     values:
   360  	//       version: 2
   361  	// - method:
   362  	//     service: foo.bar.v2
   363  	// ```
   364  	//
   365  	// For a request to match against this rule, a request should satisfy
   366  	// EITHER of the two conditions:
   367  	//
   368  	// - service of foo.bar AND contains the header `version: 2`
   369  	// - service of foo.bar.v2
   370  	//
   371  	// See the documentation for GRPCRouteMatch on how to specify multiple
   372  	// match conditions that should be ANDed together.
   373  	//
   374  	// If no matches are specified, the implementation must match every gRPC request.
   375  	//
   376  	// Proxy or Load Balancer routing configuration generated from GRPCRoutes
   377  	// MUST prioritize rules based on the following criteria, continuing on
   378  	// ties. Merging must not be done between GRPCRoutes and HTTPRoutes.
   379  	// Precedence must be given to the rule with the largest number of:
   380  	//
   381  	// * Characters in a matching non-wildcard hostname.
   382  	// * Characters in a matching hostname.
   383          // * Characters in a matching service.
   384          // * Characters in a matching method.
   385  	// * Header matches.
   386  	//
   387  	// If ties still exist across multiple Routes, matching precedence MUST be
   388  	// determined in order of the following criteria, continuing on ties:
   389  	//
   390  	// * The oldest Route based on creation timestamp.
   391  	// * The Route appearing first in alphabetical order by
   392  	//   "{namespace}/{name}".
   393  	//
   394  	// If ties still exist within the Route that has been given precedence,
   395  	// matching precedence MUST be granted to the first matching rule meeting
   396  	// the above criteria.
   397  	//
   398  	// +optional
   399  	// +kubebuilder:validation:MaxItems=8
   400  	// +kubebuilder:default={{method: {type: "Exact"}}}
   401  	Matches []GRPCRouteMatch `json:"matches,omitempty"`
   402  
   403  	// Filters define the filters that are applied to requests that match
   404  	// this rule.
   405  	//
   406  	// The effects of ordering of multiple behaviors are currently unspecified.
   407  	// This can change in the future based on feedback during the alpha stage.
   408  	//
   409  	// Conformance-levels at this level are defined based on the type of filter:
   410  	//
   411  	// - ALL core filters MUST be supported by all implementations.
   412  	// - Implementers are encouraged to support extended filters.
   413  	// - Implementation-specific custom filters have no API guarantees across
   414  	//   implementations.
   415  	//
   416  	// Specifying a core filter multiple times has unspecified or 
   417  	// implementation-specific conformance.
   418  	// Support: Core
   419  	//
   420  	// +optional
   421  	// +kubebuilder:validation:MaxItems=16
   422  	Filters []GRPCRouteFilter `json:"filters,omitempty"`
   423  
   424  	// BackendRefs defines the backend(s) where matching requests should be
   425  	// sent.
   426  
   427  	// If unspecified or invalid (refers to a non-existent resource or a Service
   428  	// with no endpoints), the rule performs no forwarding. If there are also no
   429  	// filters specified that would result in a response being sent, a gRPC `UNAVAILABLE`
   430  	// status is returned. `UNAVAILABLE` responses must be sent so that the overall
   431  	// weight is respected; if an invalid backend is requested to have 80% of
   432  	// requests, then 80% of requests must get a `UNAVAILABLE` instead.
   433  	// Support: Core for Kubernetes Service
   434  	// Support: Implementation-specific for any other resource
   435  	//
   436  	// Support for weight: Core
   437  	//
   438  	// +optional
   439  	// +kubebuilder:validation:MaxItems=16
   440  	BackendRefs []GRPCBackendRef `json:"backendRefs,omitempty"`
   441  }
   442  
   443  // GRPCRouteMatch defines the predicate used to match requests to a given
   444  // action. Multiple match types are ANDed together, i.e. the match will
   445  // evaluate to true only if all conditions are satisfied.
   446  //
   447  // For example, the match below will match a gRPC request only if its service
   448  // is `foo` AND it contains the `version: v1` header:
   449  //
   450  // ```
   451  // match:
   452  //   method:
   453  //     type: Exact
   454  //     service: "foo"
   455  //   headers:
   456  //   - name: "version"
   457  //     value "v1"
   458  // ```
   459  type GRPCRouteMatch struct {
   460  	// Path specifies a gRPC request service/method matcher. If this field is not
   461  	// specified, all services and methods will match.
   462  	//
   463  	// +optional
   464  	// +kubebuilder:default={type: "Exact"}
   465  	Method *GRPCMethodMatch `json:"path,omitempty"`
   466  
   467  	// Headers specifies gRPC request header matchers. Multiple match values are
   468  	// ANDed together, meaning, a request must match all the specified headers
   469  	// to select the route.
   470  	//
   471  	// +listType=map
   472  	// +listMapKey=name
   473  	// +optional
   474  	// +kubebuilder:validation:MaxItems=16
   475  	Headers []GRPCHeaderMatch `json:"headers,omitempty"`
   476  }
   477  
   478  // GRPCPathMatch describes how to select a gRPC route by matching the gRPC
   479  // request service and/or method..
   480  //
   481  // At least one of Service and Method must be a non-empty string.
   482  type GRPCMethodMatch struct {
   483  	// Type specifies how to match against the service and/or method.
   484  	// Support: Core (Exact with service and method specified)
   485  	//
   486  	// Support Implementation-specific (Exact with method specified but no 
   487  	// service specified)
   488  	//
   489  	// Support: Implementation-specific (RegularExpression)
   490  	//
   491  	// +optional
   492  	// +kubebuilder:default=Exact
   493  	Type *GRPCMethodMatchType `json:"type,omitempty"`
   494  
   495  
   496  	// Value of the service to match against. If left empty or omitted, will
   497  	// match all services.
   498          //
   499          // At least one of Service and Method must be a non-empty string.
   500  	// +optional
   501  	// +kubebuilder:default=""
   502  	// +kubebuilder:validation:MaxLength=1024
   503  	Service *string `json:"value,omitempty"`
   504  
   505  	// Value of the method to match against. If left empty or omitted, will
   506  	// match all services.
   507          //
   508          // At least one of Service and Method must be a non-empty string.
   509  	// +optional
   510  	// +kubebuilder:default=""
   511  	// +kubebuilder:validation:MaxLength=1024
   512  	Method *string `json:"value,omitempty"`
   513  }
   514  
   515  // MethodMatchType specifies the semantics of how gRPC methods and services should be compared.
   516  // Valid MethodMatchType values are:
   517  //
   518  // * "Exact"
   519  // * "RegularExpression"
   520  //
   521  // Exact paths must be syntactically valid:
   522  //
   523  // - Must not contain `/` character
   524  //
   525  // +kubebuilder:validation:Enum=Exact;PathPrefix;RegularExpression
   526  // +kubebuilder:validation:Enum=Exact;RegularExpression
   527  type GRPCMethodMatchType string
   528  
   529  const (
   530  	// Matches the service and/or method exactly and with case sensitivity.
   531  	PathMatchExact PathMatchType = "Exact"
   532  
   533  	// Matches if the service and/or method matches the given regular expression with
   534  	// case sensitivity.
   535  	//
   536  	// Since `"RegularExpression"` has custom conformance, implementations
   537  	// can support POSIX, PCRE, RE2 or any other regular expression dialect.
   538  	// Please read the implementation's documentation to determine the supported
   539  	// dialect.
   540  	PathMatchRegularExpression PathMatchType = "RegularExpression"
   541  )
   542  
   543  // GRPCHeaderMatch describes how to select a gRPC route by matching gRPC request
   544  // headers.
   545  type GRPCHeaderMatch struct {
   546  	// Type specifies how to match against the value of the header.
   547  	//
   548  	// +optional
   549  	// +kubebuilder:default=Exact
   550  	Type *HeaderMatchType `json:"type,omitempty"`
   551  
   552  	// Name is the name of the gRPC Header to be matched.
   553  	//
   554  	// If multiple entries specify equivalent header names, only the first
   555  	// entry with an equivalent name MUST be considered for a match. Subsequent
   556  	// entries with an equivalent header name MUST be ignored. Due to the
   557  	// case-insensitivity of header names, "foo" and "Foo" are considered
   558  	// equivalent.
   559  	Name HeaderName `json:"name"`
   560  
   561  	// Value is the value of the gRPC Header to be matched.
   562  	//
   563  	// +kubebuilder:validation:MinLength=1
   564  	// +kubebuilder:validation:MaxLength=4096
   565  	Value string `json:"value"`
   566  }
   567  
   568  // +kubebuilder:validation:Enum=Exact;RegularExpression
   569  type HeaderMatchType string
   570  
   571  // +kubebuilder:validation:MinLength=1
   572  // +kubebuilder:validation:MaxLength=256
   573  // +kubebuilder:validation:Pattern=`^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$`
   574  type HeaderName string
   575  
   576  // GRPCBackendRef defines how a GRPCRoute should forward a gRPC request.
   577  type GRPCBackendRef struct {
   578  	// BackendRef is a reference to a backend to forward matched requests to.
   579  	//
   580  	// If the referent cannot be found, this GRPCBackendRef is invalid and must
   581  	// be dropped from the Gateway. The controller must ensure the
   582  	// "ResolvedRefs" condition on the Route is set to `status: False` and not
   583  	// configure this backend in the underlying implementation.
   584  	//
   585  	// If there is a cross-namespace reference to an *existing* object
   586  	// that is not covered by a ReferenceGrant, the controller must ensure the
   587  	// "ResolvedRefs"  condition on the Route is set to `status: False`,
   588  	// with the "RefNotPermitted" reason and not configure this backend in the
   589  	// underlying implementation.
   590  	//
   591  	// In either error case, the Message of the `ResolvedRefs` Condition
   592  	// should be used to provide more detail about the problem.
   593  	//
   594  	// Support: Implementation-specific
   595  	//
   596  	// +optional
   597  	BackendRef `json:",inline"`
   598  
   599  	// Filters defined at this level should be executed if and only if the
   600  	// request is being forwarded to the backend defined here.
   601  	//
   602  	// Support: Implementation-specific (For broader support of filters, use the Filters field
   603  	// in GRPCRouteRule.)
   604  	//
   605  	// +optional
   606  	// +kubebuilder:validation:MaxItems=16
   607  	Filters []GRPCRouteFilter `json:"filters,omitempty"`
   608  }
   609  
   610  // GRPCRouteFilter defines processing steps that must be completed during the
   611  // request or response lifecycle. GRPCRouteFilters are meant as an extension
   612  // point to express processing that may be done in Gateway implementations. Some
   613  // examples include request or response modification, implementing
   614  // authentication strategies, rate-limiting, and traffic shaping. API
   615  // guarantee/conformance is defined based on the type of the filter.
   616  type GRPCRouteFilter struct {
   617  	// Type identifies the type of filter to apply. As with other API fields,
   618  	// types are classified into three conformance levels:
   619  	//
   620  	// - Core: Filter types and their corresponding configuration defined by
   621  	//   "Support: Core" in this package, e.g. "RequestHeaderModifier". All
   622  	//   implementations must support core filters.
   623  	//
   624  	// - Extended: Filter types and their corresponding configuration defined by
   625  	//   "Support: Extended" in this package, e.g. "RequestMirror". Implementers
   626  	//   are encouraged to support extended filters.
   627  	//
   628  	// - Custom: Filters that are defined and supported by specific vendors.
   629  	//   In the future, filters showing convergence in behavior across multiple
   630  	//   implementations will be considered for inclusion in extended or core
   631  	//   conformance levels. Filter-specific configuration for such filters
   632  	//   is specified using the ExtensionRef field. `Type` should be set to
   633  	//   "ExtensionRef" for custom filters.
   634  	//
   635  	// Implementers are encouraged to define custom implementation types to
   636  	// extend the core API with implementation-specific behavior.
   637  	//
   638  	// If a reference to a custom filter type cannot be resolved, the filter
   639  	// MUST NOT be skipped. Instead, requests that would have been processed by
   640  	// that filter MUST receive a HTTP error response.
   641  	//
   642  	// +unionDiscriminator
   643  	// +kubebuilder:validation:Enum=RequestHeaderModifier;RequestMirror;ExtensionRef
   644  	// <gateway:experimental:validation:Enum=RequestHeaderModifier;RequestMirror;ExtensionRef>
   645  	Type GRPCRouteFilterType `json:"type"`
   646  
   647  	// RequestHeaderModifier defines a schema for a filter that modifies request
   648  	// headers.
   649  	//
   650  	// Support: Core
   651  	//
   652  	// Support: Core
   653  	//
   654  	// +optional
   655  	RequestHeaderModifier *HTTPRequestHeaderFilter `json:"requestHeaderModifier,omitempty"`
   656  
   657  	// RequestMirror defines a schema for a filter that mirrors requests.
   658  	// Requests are sent to the specified destination, but responses from
   659  	// that destination are ignored.
   660  	//
   661  	// Support: Extended
   662  	//
   663  	// +optional
   664  	RequestMirror *HTTPRequestMirrorFilter `json:"requestMirror,omitempty"`
   665  
   666  	// ExtensionRef is an optional, implementation-specific extension to the
   667  	// "filter" behavior.  For example, resource "myroutefilter" in group
   668  	// "networking.example.net"). ExtensionRef MUST NOT be used for core and
   669  	// extended filters.
   670  	//
   671  	// Support: Implementation-specific
   672  	// Support: Implementation-specific
   673  	//
   674  	// +optional
   675  	ExtensionRef *LocalObjectReference `json:"extensionRef,omitempty"`
   676  }
   677  ```
   678  {% endraw%}
   679  
   680  
   681  
   682  
   683  ## Beta Graduation Criteria
   684  
   685  - `GRPCRoute` has been implemented by at least 2 controllers.
   686  - Conformance tests are in place for the majority of the API surface.
   687  - It is known that users of `GRPCRoute` exist.
   688  - An API review has been performed by upstream Kubernetes reviewers.
   689  
   690  ## GA Graduation Criteria
   691  
   692  - `GRPCRoute` has been implemented by at least 4 controllers.
   693  - Exhaustive conformance tests are in place.
   694  - Adoption of `GRPCRoute` has been shown to have expanded beyond its initial set of users.
   695  
   696  ## Future Enhancements
   697  
   698  Many more ideas have been discussed for the `GRPCRoute` resource, but in the
   699  interest of keeping this particular proposal tractable, they have been deferred
   700  for future proposals. Enough thought has been given to these use cases at the
   701  moment, however, that all of the following may be added at a later date in a
   702  backward-compatible manner.
   703  
   704  Some of these ideas are:
   705  
   706  - Integration with Service Meshes (both sidecar-proxied and proxyless)
   707  - Better UX for enabling reflection support
   708  - gRPC Web support
   709  - HTTP/JSON transcoding at the gateway
   710  - Protobuf payload-based routing