gateway_api/apis/standard/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 ///
130 ///
131 ///
132 ///
133 ///
134 #[serde(
135 default,
136 skip_serializing_if = "Option::is_none",
137 rename = "parentRefs"
138 )]
139 pub parent_refs: Option<Vec<ParentReference>>,
140 /// Rules are a list of GRPC matchers, filters and actions.
141 ///
142 ///
143 #[serde(default, skip_serializing_if = "Option::is_none")]
144 pub rules: Option<Vec<GRPCRouteRule>>,
145}
146/// GRPCRouteRule defines the semantics for matching a gRPC request based on
147/// conditions (matches), processing it (filters), and forwarding the request to
148/// an API object (backendRefs).
149#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema, Default, PartialEq)]
150pub struct GRPCRouteRule {
151 /// BackendRefs defines the backend(s) where matching requests should be
152 /// sent.
153 ///
154 /// Failure behavior here depends on how many BackendRefs are specified and
155 /// how many are invalid.
156 ///
157 /// If *all* entries in BackendRefs are invalid, and there are also no filters
158 /// specified in this route rule, *all* traffic which matches this rule MUST
159 /// receive an `UNAVAILABLE` status.
160 ///
161 /// See the GRPCBackendRef definition for the rules about what makes a single
162 /// GRPCBackendRef invalid.
163 ///
164 /// When a GRPCBackendRef is invalid, `UNAVAILABLE` statuses MUST be returned for
165 /// requests that would have otherwise been routed to an invalid backend. If
166 /// multiple backends are specified, and some are invalid, the proportion of
167 /// requests that would otherwise have been routed to an invalid backend
168 /// MUST receive an `UNAVAILABLE` status.
169 ///
170 /// For example, if two backends are specified with equal weights, and one is
171 /// invalid, 50 percent of traffic MUST receive an `UNAVAILABLE` status.
172 /// Implementations may choose how that 50 percent is determined.
173 ///
174 /// Support: Core for Kubernetes Service
175 ///
176 /// Support: Implementation-specific for any other resource
177 ///
178 /// Support for weight: Core
179 #[serde(
180 default,
181 skip_serializing_if = "Option::is_none",
182 rename = "backendRefs"
183 )]
184 pub backend_refs: Option<Vec<GRPCBackendReference>>,
185 /// Filters define the filters that are applied to requests that match
186 /// this rule.
187 ///
188 /// The effects of ordering of multiple behaviors are currently unspecified.
189 /// This can change in the future based on feedback during the alpha stage.
190 ///
191 /// Conformance-levels at this level are defined based on the type of filter:
192 ///
193 /// - ALL core filters MUST be supported by all implementations that support
194 /// GRPCRoute.
195 /// - Implementers are encouraged to support extended filters.
196 /// - Implementation-specific custom filters have no API guarantees across
197 /// implementations.
198 ///
199 /// Specifying the same filter multiple times is not supported unless explicitly
200 /// indicated in the filter.
201 ///
202 /// If an implementation can not support a combination of filters, it must clearly
203 /// document that limitation. In cases where incompatible or unsupported
204 /// filters are specified and cause the `Accepted` condition to be set to status
205 /// `False`, implementations may use the `IncompatibleFilters` reason to specify
206 /// this configuration error.
207 ///
208 /// Support: Core
209 #[serde(default, skip_serializing_if = "Option::is_none")]
210 pub filters: Option<Vec<GRPCRouteFilter>>,
211 /// Matches define conditions used for matching the rule against incoming
212 /// gRPC requests. Each match is independent, i.e. this rule will be matched
213 /// if **any** one of the matches is satisfied.
214 ///
215 /// For example, take the following matches configuration:
216 ///
217 /// ```text
218 /// matches:
219 /// - method:
220 /// service: foo.bar
221 /// headers:
222 /// values:
223 /// version: 2
224 /// - method:
225 /// service: foo.bar.v2
226 /// ```
227 ///
228 /// For a request to match against this rule, it MUST satisfy
229 /// EITHER of the two conditions:
230 ///
231 /// - service of foo.bar AND contains the header `version: 2`
232 /// - service of foo.bar.v2
233 ///
234 /// See the documentation for GRPCRouteMatch on how to specify multiple
235 /// match conditions to be ANDed together.
236 ///
237 /// If no matches are specified, the implementation MUST match every gRPC request.
238 ///
239 /// Proxy or Load Balancer routing configuration generated from GRPCRoutes
240 /// MUST prioritize rules based on the following criteria, continuing on
241 /// ties. Merging MUST not be done between GRPCRoutes and HTTPRoutes.
242 /// Precedence MUST be given to the rule with the largest number of:
243 ///
244 /// * Characters in a matching non-wildcard hostname.
245 /// * Characters in a matching hostname.
246 /// * Characters in a matching service.
247 /// * Characters in a matching method.
248 /// * Header matches.
249 ///
250 /// If ties still exist across multiple Routes, matching precedence MUST be
251 /// determined in order of the following criteria, continuing on ties:
252 ///
253 /// * The oldest Route based on creation timestamp.
254 /// * The Route appearing first in alphabetical order by
255 /// "{namespace}/{name}".
256 ///
257 /// If ties still exist within the Route that has been given precedence,
258 /// matching precedence MUST be granted to the first matching rule meeting
259 /// the above criteria.
260 #[serde(default, skip_serializing_if = "Option::is_none")]
261 pub matches: Option<Vec<GRPCRouteMatch>>,
262}
263/// GRPCBackendRef defines how a GRPCRoute forwards a gRPC request.
264///
265/// Note that when a namespace different than the local namespace is specified, a
266/// ReferenceGrant object is required in the referent namespace to allow that
267/// namespace's owner to accept the reference. See the ReferenceGrant
268/// documentation for details.
269///
270/// <gateway:experimental:description>
271///
272/// When the BackendRef points to a Kubernetes Service, implementations SHOULD
273/// honor the appProtocol field if it is set for the target Service Port.
274///
275/// Implementations supporting appProtocol SHOULD recognize the Kubernetes
276/// Standard Application Protocols defined in KEP-3726.
277///
278/// If a Service appProtocol isn't specified, an implementation MAY infer the
279/// backend protocol through its own means. Implementations MAY infer the
280/// protocol from the Route type referring to the backend Service.
281///
282/// If a Route is not able to send traffic to the backend using the specified
283/// protocol then the backend is considered invalid. Implementations MUST set the
284/// "ResolvedRefs" condition to "False" with the "UnsupportedProtocol" reason.
285///
286/// </gateway:experimental:description>
287#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema, Default, PartialEq)]
288pub struct GRPCBackendReference {
289 /// Filters defined at this level MUST be executed if and only if the
290 /// request is being forwarded to the backend defined here.
291 ///
292 /// Support: Implementation-specific (For broader support of filters, use the
293 /// Filters field in GRPCRouteRule.)
294 #[serde(default, skip_serializing_if = "Option::is_none")]
295 pub filters: Option<Vec<GRPCRouteFilter>>,
296 /// Group is the group of the referent. For example, "gateway.networking.k8s.io".
297 /// When unspecified or empty string, core API group is inferred.
298 #[serde(default, skip_serializing_if = "Option::is_none")]
299 pub group: Option<String>,
300 /// Kind is the Kubernetes resource kind of the referent. For example
301 /// "Service".
302 ///
303 /// Defaults to "Service" when not specified.
304 ///
305 /// ExternalName services can refer to CNAME DNS records that may live
306 /// outside of the cluster and as such are difficult to reason about in
307 /// terms of conformance. They also may not be safe to forward to (see
308 /// CVE-2021-25740 for more information). Implementations SHOULD NOT
309 /// support ExternalName Services.
310 ///
311 /// Support: Core (Services with a type other than ExternalName)
312 ///
313 /// Support: Implementation-specific (Services with type ExternalName)
314 #[serde(default, skip_serializing_if = "Option::is_none")]
315 pub kind: Option<String>,
316 /// Name is the name of the referent.
317 pub name: String,
318 /// Namespace is the namespace of the backend. When unspecified, the local
319 /// namespace is inferred.
320 ///
321 /// Note that when a namespace different than the local namespace is specified,
322 /// a ReferenceGrant object is required in the referent namespace to allow that
323 /// namespace's owner to accept the reference. See the ReferenceGrant
324 /// documentation for details.
325 ///
326 /// Support: Core
327 #[serde(default, skip_serializing_if = "Option::is_none")]
328 pub namespace: Option<String>,
329 /// Port specifies the destination port number to use for this resource.
330 /// Port is required when the referent is a Kubernetes Service. In this
331 /// case, the port number is the service port number, not the target port.
332 /// For other resources, destination port might be derived from the referent
333 /// resource or this field.
334 #[serde(default, skip_serializing_if = "Option::is_none")]
335 pub port: Option<i32>,
336 /// Weight specifies the proportion of requests forwarded to the referenced
337 /// backend. This is computed as weight/(sum of all weights in this
338 /// BackendRefs list). For non-zero values, there may be some epsilon from
339 /// the exact proportion defined here depending on the precision an
340 /// implementation supports. Weight is not a percentage and the sum of
341 /// weights does not need to equal 100.
342 ///
343 /// If only one backend is specified and it has a weight greater than 0, 100%
344 /// of the traffic is forwarded to that backend. If weight is set to 0, no
345 /// traffic should be forwarded for this entry. If unspecified, weight
346 /// defaults to 1.
347 ///
348 /// Support for this field varies based on the context where used.
349 #[serde(default, skip_serializing_if = "Option::is_none")]
350 pub weight: Option<i32>,
351}
352/// GRPCRouteMatch defines the predicate used to match requests to a given
353/// action. Multiple match types are ANDed together, i.e. the match will
354/// evaluate to true only if all conditions are satisfied.
355///
356/// For example, the match below will match a gRPC request only if its service
357/// is `foo` AND it contains the `version: v1` header:
358///
359/// ```text
360/// matches:
361/// - method:
362/// type: Exact
363/// service: "foo"
364/// headers:
365/// - name: "version"
366/// value "v1"
367///
368/// ```
369#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema, Default, PartialEq)]
370pub struct GRPCRouteMatch {
371 /// Headers specifies gRPC request header matchers. Multiple match values are
372 /// ANDed together, meaning, a request MUST match all the specified headers
373 /// to select the route.
374 #[serde(default, skip_serializing_if = "Option::is_none")]
375 pub headers: Option<Vec<HeaderMatch>>,
376 /// Method specifies a gRPC request service/method matcher. If this field is
377 /// not specified, all services and methods will match.
378 #[serde(default, skip_serializing_if = "Option::is_none")]
379 pub method: Option<GRPCMethodMatch>,
380}
381/// Method specifies a gRPC request service/method matcher. If this field is
382/// not specified, all services and methods will match.
383#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema, Default, PartialEq)]
384pub struct GRPCMethodMatch {
385 /// Value of the method to match against. If left empty or omitted, will
386 /// match all services.
387 ///
388 /// At least one of Service and Method MUST be a non-empty string.
389 #[serde(default, skip_serializing_if = "Option::is_none")]
390 pub method: Option<String>,
391 /// Value of the service to match against. If left empty or omitted, will
392 /// match any service.
393 ///
394 /// At least one of Service and Method MUST be a non-empty string.
395 #[serde(default, skip_serializing_if = "Option::is_none")]
396 pub service: Option<String>,
397 /// Type specifies how to match against the service and/or method.
398 /// Support: Core (Exact with service and method specified)
399 ///
400 /// Support: Implementation-specific (Exact with method specified but no service specified)
401 ///
402 /// Support: Implementation-specific (RegularExpression)
403 #[serde(default, skip_serializing_if = "Option::is_none", rename = "type")]
404 pub r#type: Option<HeaderMatchType>,
405}