18 releases (breaking)

0.15.0 Feb 17, 2023
0.14.0 Nov 18, 2022
0.13.0 Oct 16, 2022
0.11.0 Apr 21, 2022
0.2.1 Nov 29, 2021

#278 in Development tools

Download history 34/week @ 2022-12-03 57/week @ 2022-12-10 28/week @ 2022-12-17 14/week @ 2022-12-24 73/week @ 2022-12-31 24/week @ 2023-01-07 101/week @ 2023-01-14 106/week @ 2023-01-21 95/week @ 2023-01-28 85/week @ 2023-02-04 102/week @ 2023-02-11 219/week @ 2023-02-18 60/week @ 2023-02-25 63/week @ 2023-03-04 71/week @ 2023-03-11 59/week @ 2023-03-18

258 downloads per month


1.5K SLoC


CI Crates.io

Kubernetes openapi unmangler.

Generates rust structs from customresourcedefinitions in your kubernetes cluster following the spec/status model, by using their embedded openapi schema.

⚠️ WARNING: not feature complete ⚠️



  • Instantly queryable: generated type uses kube-derive to provide api integration with kube
  • Rust doc comments: optionally extracted from description values in schema
  • Safe case conversion: generated types uses rust standard camel_case with occasional serde rename attributes
  • Usable locally and in CI: Can read crds by name in cluster via mycrd.group.io or from file via -f crd.yaml


Grab a prebuilt musl/darwin binary from the latest release, or install from crates.io:

cargo install kopium


If you have a crd installed in your cluster, pass a crd name accessible from your KUBECONFIG:

kopium prometheusrules.monitoring.coreos.com -A > prometheusrule.rs

Or pass a file/stdin via -f:

curl -sSL https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/main/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml \
    | kopium -Af - > prometheusrule.rs


use kube::CustomResource;
use schemars::JsonSchema;
use serde::{Serialize, Deserialize};
use std::collections::BTreeMap;
use k8s_openapi::apimachinery::pkg::util::intstr::IntOrString;

/// Specification of desired alerting rule definitions for Prometheus.
#[derive(CustomResource, Serialize, Deserialize, Clone, Debug, JsonSchema)]
#[kube(group = "monitoring.coreos.com", version = "v1", kind = "PrometheusRule", plural = "prometheusrules")]
pub struct PrometheusRuleSpec {
    /// Content of Prometheus rule file
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub groups: Option<Vec<PrometheusRuleGroups>>,

/// RuleGroup is a list of sequentially evaluated recording and alerting rules.
#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)]
pub struct PrometheusRuleGroups {
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub interval: Option<String>,
    pub name: String,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub partial_response_strategy: Option<String>,
    pub rules: Vec<PrometheusRuleGroupsRules>,

/// Rule describes an alerting or recording rule
#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)]
pub struct PrometheusRuleGroupsRules {
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub alert: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub annotations: Option<BTreeMap<String, String>>,
    pub expr: IntOrString,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub r#for: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub labels: Option<BTreeMap<String, String>>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub record: Option<String>,

Usage with kube

Simply add the generated file (e.g. output from above in prometheusrule.rs) to your library, and import (at least) the special root type:

use prometheusrule::PrometheusRule;
use kube::{Api, Client, ResourceExt};

async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Client::try_default().await?;
    let pr: Api<PrometheusRule> = Api::default_namespaced(client);
    for p in pr.list(&Default::default()).await? {
        println!("Found PrometheusRule {} in current namespace", p.name());


Autocompletion for most shells available via kopium completions:

source <(kopium completions bash)


Unit tests and running kopium from a file do not require a cluster and can be run with:

cargo test --lib
cargo run --bin kopium -- -f mycrd.yaml -A

Full integration tests use your current cluster to try to read a CRD and a gen object (instance of the CRD type) and parse it into the generated type:

cargo run --bin kopium -- -f prometheusrules.monitoring.coreos.com > tests/gen.rs
echo "pub type CR = PrometheusRule;" >> tests/gen.rs
kubectl apply -f tests/pr.yaml # needs to contain a CR with name "gen"
cargo test --test runner -- --nocapture

test shortcuts available via just in the justfile and run pre-merge.


Apache 2.0 licensed. See LICENSE for details.


~1.5M SLoC