k8s_openapi/
lib.rs

1#![warn(rust_2018_idioms)]
2#![deny(clippy::all, clippy::pedantic)]
3#![allow(
4    clippy::default_trait_access,
5    clippy::derive_partial_eq_without_eq,
6    clippy::doc_lazy_continuation,
7    clippy::doc_markdown,
8    clippy::doc_overindented_list_items,
9    clippy::large_enum_variant,
10    clippy::match_single_binding,
11    clippy::missing_errors_doc,
12    clippy::module_name_repetitions,
13    clippy::must_use_candidate,
14    clippy::similar_names,
15    clippy::single_match_else,
16    clippy::too_many_lines,
17    clippy::type_complexity,
18    rustdoc::bare_urls,
19)]
20
21// `schemars::json_schema!` expansion hits recursion limit.
22#![cfg_attr(feature = "schemars", recursion_limit = "256")]
23
24//! Bindings for the Kubernetes client API, generated from the OpenAPI spec.
25//!
26//! Each supported version of Kubernetes is represented by a feature name (like `v1_9`). Only one such feature can be enabled at a time.
27//!
28//! These docs have been generated with the `
29
30#![cfg_attr(k8s_openapi_enabled_version="1.30", doc = "v1_30")]
31#![cfg_attr(k8s_openapi_enabled_version="1.31", doc = "v1_31")]
32#![cfg_attr(k8s_openapi_enabled_version="1.32", doc = "v1_32")]
33#![cfg_attr(k8s_openapi_enabled_version="1.33", doc = "v1_33")]
34#![cfg_attr(k8s_openapi_enabled_version="1.34", doc = "v1_34")]
35
36//! ` feature enabled. To see docs for one of the other supported versions, please generate the docs locally with `cargo doc --features 'v1_<>'`
37//!
38//!
39//! # Examples
40//!
41//! ## Resources
42//!
43//! This example creates an instance of [`api::core::v1::PodSpec`] with no other properties set, and pretty-prints it.
44//!
45//! ```rust
46//! use k8s_openapi::api::core::v1 as api;
47//!
48//! fn main() {
49//!     let pod_spec: api::PodSpec = Default::default();
50//!     println!("{pod_spec:#?}");
51//! }
52//! ```
53//!
54//!
55//! # Crate features
56//!
57//! This crate contains several `v1_*` features. Enabling one of the `v1_*` features selects which version of the Kubernetes API server this crate should target.
58//! For example, enabling the `v1_50` feature means the crate will only contain the API exposed by Kubernetes 1.50. It will not expose API
59//! that were removed in 1.50 or earlier, nor any API added in 1.51 or later.
60//!
61//! One and only one of the `v1_*` features must be enabled at the same time, otherwise the crate will not compile. This ensures that all crates in the crate graph
62//! use the same types. If it was possible for one library crate to use `api::core::v1::Pod` corresponding to v1.50 and another to use the type
63//! corresponding to v1.51, an application would not be able to use the same `Pod` value with both.
64//!
65//! Thus, it is recommended that only application crates must enable one of the `v1_*` features, corresponding to the version of Kubernetes
66//! that the application wants to support.
67//!
68//! ```toml
69//! # For application crates
70//!
71//! [dependencies]
72//! k8s-openapi = { version = "...", features = ["v1_50"] }
73//! ```
74//!
75//! If you're writing a library crate, your crate *must not* enable any features of `k8s-openapi` directly. The choice of which feature to enable
76//! must be left to any application crates that use your library. This ensures that all `k8s-openapi`-using dependencies in that application crate's dependency graph
77//! use the same set of `k8s-openapi` types and are interoperable.
78//!
79//! If your library crate has tests or examples, you should also add a dev-dependency on `k8s-openapi` in addition to the direct dependency,
80//! and enable a version feature only for that dev-dependency.
81//!
82//! ```toml
83//! # For library crates
84//!
85//! [dependencies]
86//! k8s-openapi = "..."
87//!
88//! [dev-dependencies]
89//! k8s-openapi = { version = "...", features = ["v1_50"] }
90//! ```
91//!
92//! However, commands like `cargo check` and `cargo doc` do not build dev dependencies, so they will not enable the feature and will fail to build. There are two ways
93//! you can resolve this:
94//!
95//! 1. Add a feature to your library that enables one of the k8s-openapi `v1_*` features, and then remember to enable this feature when running such commands.
96//!
97//!    ```toml
98//!    [features]
99//!    __check = ["k8s-openapi/v1_50"]
100//!    ```
101//!
102//!    ```sh
103//!    $ cargo check --features __check
104//!    ```
105//!
106//! 1. Define the `K8S_OPENAPI_ENABLED_VERSION` env var when running such commands:
107//!
108//!    ```sh
109//!    $ K8S_OPENAPI_ENABLED_VERSION=1.50 cargo check
110//!    ```
111//!
112//!
113//! # Conditional compilation
114//!
115//! As the previous section explained, library crates must not enable any version features in their `k8s-openapi` dependency. However, your library crate may
116//! need to know about which version gets selected eventually.
117//!
118//! For example:
119//!
120//! 1. Your crate creates a `PodSecurityContext` and wants to set the `supplemental_groups_policy` field. This field is only available in Kubernetes 1.31+,
121//!    so you want your crate to fail to compile if a lower feature was enabled.
122//!
123//! 1. Your crate creates a `PodSecurityContext` and wants to set the `supplemental_groups_policy` field, but it's okay to not set it when compiling for older versions.
124//!
125//! There are two ways for your crate to determine which feature of `k8s-openapi` is enabled:
126//!
127//! 1. The `k8s-openapi` crate exports [`k8s_if_*` macros,](#macros) which either expand to their contents or don't. See the docs of the macros for more details.
128//!
129//!    With these macros, the two cases above would be solved like this:
130//!
131//!    - ```rust,ignore
132//!      // The compile_error!() is only emitted if 1.30 or lower is selected.
133//!      k8s_openapi::k8s_if_le_1_30! {
134//!          compile_error!("This crate requires the v1_31 (or higher) feature to be enabled on the k8s-openapi crate.");
135//!      }
136//!
137//!      ...
138//!
139//!      let pod_security_context = k8s_openapi::api::core::v1::PodSecurityContext {
140//!          supplemental_groups_policy: ...,
141//!          ...
142//!      };
143//!      ```
144//!
145//!    - ```rust,ignore
146//!      let mut pod_security_context = k8s_openapi::api::core::v1::PodSecurityContext {
147//!          ...
148//!      };
149//!
150//!      k8s_openapi::k8s_if_ge_1_31! {
151//!          pod_security_context.supplemental_groups_policy = ...;
152//!      }
153//!      ```
154//!
155//! 1. The `k8s-openapi` crate emits the selected version number as metadata that your crate can read in a build script
156//!    from the `DEP_K8S_OPENAPI_*_VERSION` env var.
157//!
158//!    ```rust,no_run
159//!    // Your crate's build.rs
160//!
161//!    fn main() {
162//!        let k8s_openapi_version: u32 =
163//!            std::env::vars_os()
164//!            .find_map(|(key, value)| {
165//!                let key = key.into_string().ok()?;
166//!                if key.starts_with("DEP_K8S_OPENAPI_") && key.ends_with("_VERSION") {
167//!                    let value = value.into_string().ok()?;
168//!                    Some(value)
169//!                }
170//!                else {
171//!                    None
172//!                }
173//!            }).expect("DEP_K8S_OPENAPI_*_VERSION must have been set by k8s-openapi")
174//!            .parse().expect("DEP_K8S_OPENAPI_*_VERSION is malformed");
175//!
176//!        // k8s_openapi_version has the format 0x00_MM_NN_00.
177//!        //
178//!        // - MM is the major version.
179//!        // - NN is the minor version.
180//!        //
181//!        // Thus, if the v1_31 feature was enabled, k8s_openapi_version would be 0x00_01_1F_00
182//!
183//!        // The build script can now do arbitrary things with the information.
184//!        // For example, it could define custom cfgs:
185//!        if k8s_openapi_version >= 0x00_01_1F_00 {
186//!            println!(r#"cargo::rustc-cfg=k8s_pod_security_context_supports_supplemental_groups_policy"#);
187//!        }
188//!
189//!        // ... or emit new source code files under OUT_DIR, or anything else a build script can do.
190//!    }
191//!    ```
192//!
193//!    With this cfg, the two cases above would be solved like this:
194//!
195//!    - ```rust,ignore
196//!      // The compile_error!() is only emitted if 1.30 or lower is selected.
197//!      #[cfg(not(k8s_pod_security_context_supports_supplemental_groups_policy))]
198//!      compile_error!("This crate requires the v1_31 (or higher) feature to be enabled on the k8s-openapi crate.");
199//!
200//!      ...
201//!
202//!      let pod_security_context = k8s_openapi::api::core::v1::PodSecurityContext {
203//!          supplemental_groups_policy: ...,
204//!          ...
205//!      };
206//!      ```
207//!
208//!    - ```rust,ignore
209//!      let pod_security_context = k8s_openapi::api::core::v1::PodSecurityContext {
210//!          #[cfg(not(k8s_pod_security_context_supports_supplemental_groups_policy))]
211//!          supplemental_groups_policy: ...,
212//!          ...
213//!      };
214//!      ```
215//!
216//! Note that both approaches require your crate to have a direct dependency on the `k8s-openapi` crate. Neither approach is available if your crate
217//! only has a transitive dependency on the `k8s-openapi` crate.
218//!
219//! The macros approach is easier to use since it doesn't require a build script.
220//!
221//! The build script method lets you emit arbitrary cfgs, emit arbitrary source code, and generally gives you more options, at the cost of needing a build script.
222//! `cfg()`s can be used in places where macros cannot, such as how the second example above shows it being used on a single field in a struct literal.
223//!
224//!
225//! # Custom resource definitions
226//!
227//! The [`k8s-openapi-derive` crate](https://crates.io/crates/k8s-openapi-derive) provides a custom derive for generating types
228//! for custom resources. See that crate's docs for more information.
229
230#![no_std]
231
232#[cfg(not(feature = "std"))]
233extern crate alloc as std;
234#[cfg(feature = "std")]
235extern crate std;
236
237pub use chrono;
238#[cfg(feature = "schemars")]
239pub use schemars;
240pub use serde;
241pub use serde_json;
242
243
244#[path = "byte_string.rs"]
245mod _byte_string;
246pub use _byte_string::ByteString;
247
248#[path = "deep_merge.rs"]
249mod _deep_merge;
250pub use self::_deep_merge::{DeepMerge, strategies as merge_strategies};
251
252#[path = "resource.rs"]
253mod _resource;
254pub use _resource::{
255    Resource,
256    ResourceScope, ClusterResourceScope, NamespaceResourceScope, SubResourceScope,
257    ListableResource,
258    Metadata,
259    api_version, group, kind, version,
260};
261
262#[cfg(k8s_openapi_enabled_version="1.30")] mod v1_30;
263#[cfg(k8s_openapi_enabled_version="1.30")] pub use self::v1_30::*;
264
265#[cfg(k8s_openapi_enabled_version="1.31")] mod v1_31;
266#[cfg(k8s_openapi_enabled_version="1.31")] pub use self::v1_31::*;
267
268#[cfg(k8s_openapi_enabled_version="1.32")] mod v1_32;
269#[cfg(k8s_openapi_enabled_version="1.32")] pub use self::v1_32::*;
270
271#[cfg(k8s_openapi_enabled_version="1.33")] mod v1_33;
272#[cfg(k8s_openapi_enabled_version="1.33")] pub use self::v1_33::*;
273
274#[cfg(k8s_openapi_enabled_version="1.34")] mod v1_34;
275#[cfg(k8s_openapi_enabled_version="1.34")] pub use self::v1_34::*;
276
277include!(concat!(env!("OUT_DIR"), "/conditional_compilation_macros.rs"));