gateway_api/apis/experimental/
grpcroutes.rs

1// WARNING: generated file - manual changes will be overriden
2
3use super::common::*;
4#[allow(unused_imports)]
5mod prelude {
6    pub use k8s_openapi::apimachinery::pkg::apis::meta::v1::Condition;
7    pub use kube_derive::CustomResource;
8    pub use schemars::JsonSchema;
9    pub use serde::{Deserialize, Serialize};
10}
11use self::prelude::*;
12/// Spec defines the desired state of GRPCRoute.
13#[derive(CustomResource, Serialize, Deserialize, Clone, Debug, JsonSchema, Default, PartialEq)]
14#[kube(
15    group = "gateway.networking.k8s.io",
16    version = "v1",
17    kind = "GRPCRoute",
18    plural = "grpcroutes"
19)]
20#[kube(namespaced)]
21#[kube(status = "RouteStatus")]
22#[kube(derive = "Default")]
23#[kube(derive = "PartialEq")]
24pub struct GRPCRouteSpec {
25    /// Hostnames defines a set of hostnames to match against the GRPC
26    /// Host header to select a GRPCRoute to process the request. This matches
27    /// the RFC 1123 definition of a hostname with 2 notable exceptions:
28    ///
29    /// 1. IPs are not allowed.
30    /// 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard
31    ///    label MUST appear by itself as the first label.
32    ///
33    /// If a hostname is specified by both the Listener and GRPCRoute, there
34    /// MUST be at least one intersecting hostname for the GRPCRoute to be
35    /// attached to the Listener. For example:
36    ///
37    /// * A Listener with `test.example.com` as the hostname matches GRPCRoutes
38    ///   that have either not specified any hostnames, or have specified at
39    ///   least one of `test.example.com` or `*.example.com`.
40    /// * A Listener with `*.example.com` as the hostname matches GRPCRoutes
41    ///   that have either not specified any hostnames or have specified at least
42    ///   one hostname that matches the Listener hostname. For example,
43    ///   `test.example.com` and `*.example.com` would both match. On the other
44    ///   hand, `example.com` and `test.example.net` would not match.
45    ///
46    /// Hostnames that are prefixed with a wildcard label (`*.`) are interpreted
47    /// as a suffix match. That means that a match for `*.example.com` would match
48    /// both `test.example.com`, and `foo.test.example.com`, but not `example.com`.
49    ///
50    /// If both the Listener and GRPCRoute have specified hostnames, any
51    /// GRPCRoute hostnames that do not match the Listener hostname MUST be
52    /// ignored. For example, if a Listener specified `*.example.com`, and the
53    /// GRPCRoute specified `test.example.com` and `test.example.net`,
54    /// `test.example.net` MUST NOT be considered for a match.
55    ///
56    /// If both the Listener and GRPCRoute have specified hostnames, and none
57    /// match with the criteria above, then the GRPCRoute MUST NOT be accepted by
58    /// the implementation. The implementation MUST raise an 'Accepted' Condition
59    /// with a status of `False` in the corresponding RouteParentStatus.
60    ///
61    /// If a Route (A) of type HTTPRoute or GRPCRoute is attached to a
62    /// Listener and that listener already has another Route (B) of the other
63    /// type attached and the intersection of the hostnames of A and B is
64    /// non-empty, then the implementation MUST accept exactly one of these two
65    /// routes, determined by the following criteria, in order:
66    ///
67    /// * The oldest Route based on creation timestamp.
68    /// * The Route appearing first in alphabetical order by
69    ///   "{namespace}/{name}".
70    ///
71    /// The rejected Route MUST raise an 'Accepted' condition with a status of
72    /// 'False' in the corresponding RouteParentStatus.
73    ///
74    /// Support: Core
75    #[serde(default, skip_serializing_if = "Option::is_none")]
76    pub hostnames: Option<Vec<String>>,
77    /// ParentRefs references the resources (usually Gateways) that a Route wants
78    /// to be attached to. Note that the referenced parent resource needs to
79    /// allow this for the attachment to be complete. For Gateways, that means
80    /// the Gateway needs to allow attachment from Routes of this kind and
81    /// namespace. For Services, that means the Service must either be in the same
82    /// namespace for a "producer" route, or the mesh implementation must support
83    /// and allow "consumer" routes for the referenced Service. ReferenceGrant is
84    /// not applicable for governing ParentRefs to Services - it is not possible to
85    /// create a "producer" route for a Service in a different namespace from the
86    /// Route.
87    ///
88    /// There are two kinds of parent resources with "Core" support:
89    ///
90    /// * Gateway (Gateway conformance profile)
91    /// * Service (Mesh conformance profile, ClusterIP Services only)
92    ///
93    /// This API may be extended in the future to support additional kinds of parent
94    /// resources.
95    ///
96    /// ParentRefs must be _distinct_. This means either that:
97    ///
98    /// * They select different objects.  If this is the case, then parentRef
99    ///   entries are distinct. In terms of fields, this means that the
100    ///   multi-part key defined by `group`, `kind`, `namespace`, and `name` must
101    ///   be unique across all parentRef entries in the Route.
102    /// * They do not select different objects, but for each optional field used,
103    ///   each ParentRef that selects the same object must set the same set of
104    ///   optional fields to different values. If one ParentRef sets a
105    ///   combination of optional fields, all must set the same combination.
106    ///
107    /// Some examples:
108    ///
109    /// * If one ParentRef sets `sectionName`, all ParentRefs referencing the
110    ///   same object must also set `sectionName`.
111    /// * If one ParentRef sets `port`, all ParentRefs referencing the same
112    ///   object must also set `port`.
113    /// * If one ParentRef sets `sectionName` and `port`, all ParentRefs
114    ///   referencing the same object must also set `sectionName` and `port`.
115    ///
116    /// It is possible to separately reference multiple distinct objects that may
117    /// be collapsed by an implementation. For example, some implementations may
118    /// choose to merge compatible Gateway Listeners together. If that is the
119    /// case, the list of routes attached to those resources should also be
120    /// merged.
121    ///
122    /// Note that for ParentRefs that cross namespace boundaries, there are specific
123    /// rules. Cross-namespace references are only valid if they are explicitly
124    /// allowed by something in the namespace they are referring to. For example,
125    /// Gateway has the AllowedRoutes field, and ReferenceGrant provides a
126    /// generic way to enable other kinds of cross-namespace reference.
127    ///
128    ///
129    /// ParentRefs from a Route to a Service in the same namespace are "producer"
130    /// routes, which apply default routing rules to inbound connections from
131    /// any namespace to the Service.
132    ///
133    /// ParentRefs from a Route to a Service in a different namespace are
134    /// "consumer" routes, and these routing rules are only applied to outbound
135    /// connections originating from the same namespace as the Route, for which
136    /// the intended destination of the connections are a Service targeted as a
137    /// ParentRef of the Route.
138    ///
139    ///
140    ///
141    ///
142    ///
143    ///
144    #[serde(
145        default,
146        skip_serializing_if = "Option::is_none",
147        rename = "parentRefs"
148    )]
149    pub parent_refs: Option<Vec<ParentReference>>,
150    /// Rules are a list of GRPC matchers, filters and actions.
151    ///
152    ///
153    #[serde(default, skip_serializing_if = "Option::is_none")]
154    pub rules: Option<Vec<GRPCRouteRule>>,
155}
156/// GRPCRouteRule defines the semantics for matching a gRPC request based on
157/// conditions (matches), processing it (filters), and forwarding the request to
158/// an API object (backendRefs).
159#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema, Default, PartialEq)]
160pub struct GRPCRouteRule {
161    /// BackendRefs defines the backend(s) where matching requests should be
162    /// sent.
163    ///
164    /// Failure behavior here depends on how many BackendRefs are specified and
165    /// how many are invalid.
166    ///
167    /// If *all* entries in BackendRefs are invalid, and there are also no filters
168    /// specified in this route rule, *all* traffic which matches this rule MUST
169    /// receive an `UNAVAILABLE` status.
170    ///
171    /// See the GRPCBackendRef definition for the rules about what makes a single
172    /// GRPCBackendRef invalid.
173    ///
174    /// When a GRPCBackendRef is invalid, `UNAVAILABLE` statuses MUST be returned for
175    /// requests that would have otherwise been routed to an invalid backend. If
176    /// multiple backends are specified, and some are invalid, the proportion of
177    /// requests that would otherwise have been routed to an invalid backend
178    /// MUST receive an `UNAVAILABLE` status.
179    ///
180    /// For example, if two backends are specified with equal weights, and one is
181    /// invalid, 50 percent of traffic MUST receive an `UNAVAILABLE` status.
182    /// Implementations may choose how that 50 percent is determined.
183    ///
184    /// Support: Core for Kubernetes Service
185    ///
186    /// Support: Implementation-specific for any other resource
187    ///
188    /// Support for weight: Core
189    #[serde(
190        default,
191        skip_serializing_if = "Option::is_none",
192        rename = "backendRefs"
193    )]
194    pub backend_refs: Option<Vec<GRPCBackendReference>>,
195    /// Filters define the filters that are applied to requests that match
196    /// this rule.
197    ///
198    /// The effects of ordering of multiple behaviors are currently unspecified.
199    /// This can change in the future based on feedback during the alpha stage.
200    ///
201    /// Conformance-levels at this level are defined based on the type of filter:
202    ///
203    /// - ALL core filters MUST be supported by all implementations that support
204    ///   GRPCRoute.
205    /// - Implementers are encouraged to support extended filters.
206    /// - Implementation-specific custom filters have no API guarantees across
207    ///   implementations.
208    ///
209    /// Specifying the same filter multiple times is not supported unless explicitly
210    /// indicated in the filter.
211    ///
212    /// If an implementation can not support a combination of filters, it must clearly
213    /// document that limitation. In cases where incompatible or unsupported
214    /// filters are specified and cause the `Accepted` condition to be set to status
215    /// `False`, implementations may use the `IncompatibleFilters` reason to specify
216    /// this configuration error.
217    ///
218    /// Support: Core
219    #[serde(default, skip_serializing_if = "Option::is_none")]
220    pub filters: Option<Vec<GRPCRouteFilter>>,
221    /// Matches define conditions used for matching the rule against incoming
222    /// gRPC requests. Each match is independent, i.e. this rule will be matched
223    /// if **any** one of the matches is satisfied.
224    ///
225    /// For example, take the following matches configuration:
226    ///
227    /// ```text
228    /// matches:
229    /// - method:
230    ///     service: foo.bar
231    ///   headers:
232    ///     values:
233    ///       version: 2
234    /// - method:
235    ///     service: foo.bar.v2
236    /// ```
237    ///
238    /// For a request to match against this rule, it MUST satisfy
239    /// EITHER of the two conditions:
240    ///
241    /// - service of foo.bar AND contains the header `version: 2`
242    /// - service of foo.bar.v2
243    ///
244    /// See the documentation for GRPCRouteMatch on how to specify multiple
245    /// match conditions to be ANDed together.
246    ///
247    /// If no matches are specified, the implementation MUST match every gRPC request.
248    ///
249    /// Proxy or Load Balancer routing configuration generated from GRPCRoutes
250    /// MUST prioritize rules based on the following criteria, continuing on
251    /// ties. Merging MUST not be done between GRPCRoutes and HTTPRoutes.
252    /// Precedence MUST be given to the rule with the largest number of:
253    ///
254    /// * Characters in a matching non-wildcard hostname.
255    /// * Characters in a matching hostname.
256    /// * Characters in a matching service.
257    /// * Characters in a matching method.
258    /// * Header matches.
259    ///
260    /// If ties still exist across multiple Routes, matching precedence MUST be
261    /// determined in order of the following criteria, continuing on ties:
262    ///
263    /// * The oldest Route based on creation timestamp.
264    /// * The Route appearing first in alphabetical order by
265    ///   "{namespace}/{name}".
266    ///
267    /// If ties still exist within the Route that has been given precedence,
268    /// matching precedence MUST be granted to the first matching rule meeting
269    /// the above criteria.
270    #[serde(default, skip_serializing_if = "Option::is_none")]
271    pub matches: Option<Vec<GRPCRouteMatch>>,
272    /// Name is the name of the route rule. This name MUST be unique within a Route if it is set.
273    ///
274    /// Support: Extended
275    ///
276    #[serde(default, skip_serializing_if = "Option::is_none")]
277    pub name: Option<String>,
278    /// SessionPersistence defines and configures session persistence
279    /// for the route rule.
280    ///
281    /// Support: Extended
282    ///
283    ///
284    #[serde(
285        default,
286        skip_serializing_if = "Option::is_none",
287        rename = "sessionPersistence"
288    )]
289    pub session_persistence: Option<SessionPersistence>,
290}
291/// GRPCBackendRef defines how a GRPCRoute forwards a gRPC request.
292///
293/// Note that when a namespace different than the local namespace is specified, a
294/// ReferenceGrant object is required in the referent namespace to allow that
295/// namespace's owner to accept the reference. See the ReferenceGrant
296/// documentation for details.
297///
298/// <gateway:experimental:description>
299///
300/// When the BackendRef points to a Kubernetes Service, implementations SHOULD
301/// honor the appProtocol field if it is set for the target Service Port.
302///
303/// Implementations supporting appProtocol SHOULD recognize the Kubernetes
304/// Standard Application Protocols defined in KEP-3726.
305///
306/// If a Service appProtocol isn't specified, an implementation MAY infer the
307/// backend protocol through its own means. Implementations MAY infer the
308/// protocol from the Route type referring to the backend Service.
309///
310/// If a Route is not able to send traffic to the backend using the specified
311/// protocol then the backend is considered invalid. Implementations MUST set the
312/// "ResolvedRefs" condition to "False" with the "UnsupportedProtocol" reason.
313///
314/// </gateway:experimental:description>
315#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema, Default, PartialEq)]
316pub struct GRPCBackendReference {
317    /// Filters defined at this level MUST be executed if and only if the
318    /// request is being forwarded to the backend defined here.
319    ///
320    /// Support: Implementation-specific (For broader support of filters, use the
321    /// Filters field in GRPCRouteRule.)
322    #[serde(default, skip_serializing_if = "Option::is_none")]
323    pub filters: Option<Vec<GRPCRouteFilter>>,
324    /// Group is the group of the referent. For example, "gateway.networking.k8s.io".
325    /// When unspecified or empty string, core API group is inferred.
326    #[serde(default, skip_serializing_if = "Option::is_none")]
327    pub group: Option<String>,
328    /// Kind is the Kubernetes resource kind of the referent. For example
329    /// "Service".
330    ///
331    /// Defaults to "Service" when not specified.
332    ///
333    /// ExternalName services can refer to CNAME DNS records that may live
334    /// outside of the cluster and as such are difficult to reason about in
335    /// terms of conformance. They also may not be safe to forward to (see
336    /// CVE-2021-25740 for more information). Implementations SHOULD NOT
337    /// support ExternalName Services.
338    ///
339    /// Support: Core (Services with a type other than ExternalName)
340    ///
341    /// Support: Implementation-specific (Services with type ExternalName)
342    #[serde(default, skip_serializing_if = "Option::is_none")]
343    pub kind: Option<String>,
344    /// Name is the name of the referent.
345    pub name: String,
346    /// Namespace is the namespace of the backend. When unspecified, the local
347    /// namespace is inferred.
348    ///
349    /// Note that when a namespace different than the local namespace is specified,
350    /// a ReferenceGrant object is required in the referent namespace to allow that
351    /// namespace's owner to accept the reference. See the ReferenceGrant
352    /// documentation for details.
353    ///
354    /// Support: Core
355    #[serde(default, skip_serializing_if = "Option::is_none")]
356    pub namespace: Option<String>,
357    /// Port specifies the destination port number to use for this resource.
358    /// Port is required when the referent is a Kubernetes Service. In this
359    /// case, the port number is the service port number, not the target port.
360    /// For other resources, destination port might be derived from the referent
361    /// resource or this field.
362    #[serde(default, skip_serializing_if = "Option::is_none")]
363    pub port: Option<i32>,
364    /// Weight specifies the proportion of requests forwarded to the referenced
365    /// backend. This is computed as weight/(sum of all weights in this
366    /// BackendRefs list). For non-zero values, there may be some epsilon from
367    /// the exact proportion defined here depending on the precision an
368    /// implementation supports. Weight is not a percentage and the sum of
369    /// weights does not need to equal 100.
370    ///
371    /// If only one backend is specified and it has a weight greater than 0, 100%
372    /// of the traffic is forwarded to that backend. If weight is set to 0, no
373    /// traffic should be forwarded for this entry. If unspecified, weight
374    /// defaults to 1.
375    ///
376    /// Support for this field varies based on the context where used.
377    #[serde(default, skip_serializing_if = "Option::is_none")]
378    pub weight: Option<i32>,
379}
380/// GRPCRouteMatch defines the predicate used to match requests to a given
381/// action. Multiple match types are ANDed together, i.e. the match will
382/// evaluate to true only if all conditions are satisfied.
383///
384/// For example, the match below will match a gRPC request only if its service
385/// is `foo` AND it contains the `version: v1` header:
386///
387/// ```text
388/// matches:
389///   - method:
390///     type: Exact
391///     service: "foo"
392///     headers:
393///   - name: "version"
394///     value "v1"
395///
396/// ```
397#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema, Default, PartialEq)]
398pub struct GRPCRouteMatch {
399    /// Headers specifies gRPC request header matchers. Multiple match values are
400    /// ANDed together, meaning, a request MUST match all the specified headers
401    /// to select the route.
402    #[serde(default, skip_serializing_if = "Option::is_none")]
403    pub headers: Option<Vec<HeaderMatch>>,
404    /// Method specifies a gRPC request service/method matcher. If this field is
405    /// not specified, all services and methods will match.
406    #[serde(default, skip_serializing_if = "Option::is_none")]
407    pub method: Option<GRPCMethodMatch>,
408}
409/// Method specifies a gRPC request service/method matcher. If this field is
410/// not specified, all services and methods will match.
411#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema, Default, PartialEq)]
412pub struct GRPCMethodMatch {
413    /// Value of the method to match against. If left empty or omitted, will
414    /// match all services.
415    ///
416    /// At least one of Service and Method MUST be a non-empty string.
417    #[serde(default, skip_serializing_if = "Option::is_none")]
418    pub method: Option<String>,
419    /// Value of the service to match against. If left empty or omitted, will
420    /// match any service.
421    ///
422    /// At least one of Service and Method MUST be a non-empty string.
423    #[serde(default, skip_serializing_if = "Option::is_none")]
424    pub service: Option<String>,
425    /// Type specifies how to match against the service and/or method.
426    /// Support: Core (Exact with service and method specified)
427    ///
428    /// Support: Implementation-specific (Exact with method specified but no service specified)
429    ///
430    /// Support: Implementation-specific (RegularExpression)
431    #[serde(default, skip_serializing_if = "Option::is_none", rename = "type")]
432    pub r#type: Option<HeaderMatchType>,
433}