Skip to content

Commit

Permalink
Fix --derive not adding derives to child structs
Browse files Browse the repository at this point in the history
Signed-off-by: clux <sszynrae@gmail.com>
  • Loading branch information
clux committed Apr 21, 2022
1 parent cdd003b commit 10e6b01
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 10 deletions.
37 changes: 29 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ Requirements:
## Features

- **Instantly queryable**: generated type uses [`kube-derive`](https://docs.rs/kube/latest/kube/derive.CustomResource.html) to provide api integration with `kube`
- **[Rust doc comments](https://doc.rust-lang.org/rust-by-example/meta/doc.html#doc-comments)**: optionally extracted from `description` values in schema (`--docs`)
- **[Rust doc comments](https://doc.rust-lang.org/rust-by-example/meta/doc.html#doc-comments)**: optionally extracted from `description` values in schema
- **Safe case conversion**: generated types uses rust standard camel_case with occasional serde rename annotations
- **Usable in CI or locally**: Can read crds via `-f crd.yaml` OR a `mycrd.group.io` crd name in cluster

## Installation

Expand All @@ -29,29 +31,40 @@ cargo install kopium

## Usage

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

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

Or pass a file/stdin via `-f`:

```sh
kopium prometheusrules.monitoring.coreos.com --docs > prometheusrule.rs
curl -sSL https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/main/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml \
| kopium -f - -A > prometheusrule.rs
```

## Output

```rust
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)]
#[derive(CustomResource, Serialize, Deserialize, Clone, Debug, JsonSchema)]
#[kube(group = "monitoring.coreos.com", version = "v1", kind = "PrometheusRule", plural = "prometheusrules")]
#[kube(namespaced)]
#[kube(schema = "disabled")]
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. Note: PartialResponseStrategy is only used by ThanosRuler and will be ignored by Prometheus instances. Valid values for this field are 'warn' or 'abort'. More info: https://github.com/thanos-io/thanos/blob/main/docs/components/rule.md#partial-response
#[derive(CustomResource, Serialize, Deserialize, Clone, Debug, JsonSchema)]
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct PrometheusRuleGroups {
#[serde(default, skip_serializing_if = "Option::is_none")]
Expand All @@ -63,13 +76,14 @@ pub struct PrometheusRuleGroups {
}

/// Rule describes an alerting or recording rule See Prometheus documentation: [alerting](https://www.prometheus.io/docs/prometheus/latest/configuration/alerting_rules/) or [recording](https://www.prometheus.io/docs/prometheus/latest/configuration/recording_rules/#recording-rules) rule
#[derive(CustomResource, Serialize, Deserialize, Clone, Debug, JsonSchema)]
#[derive(Serialize, Deserialize, Clone, Debug)]
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: 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")]
Expand Down Expand Up @@ -109,16 +123,23 @@ source <(kopium completions bash)

## Testing

Generate a CRD, tell the test runner to try to use it.
Unit tests and running `kopium` from a file do not require a cluster and can be run with:

```sh
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:

```sh
cargo run --bin kopium -- prometheusrules.monitoring.coreos.com > tests/gen.rs
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`](./justfile).
test shortcuts available via `just` in the [`justfile`](./justfile) and run pre-merge.

## License

Expand Down
2 changes: 1 addition & 1 deletion justfile
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ test-linkerd-serverauth:

test-linkerd-server:
kubectl apply --server-side -f tests/server-crd.yaml
cargo run --bin kopium -- -di servers.policy.linkerd.io > tests/gen.rs
cargo run --bin kopium -- -iA servers.policy.linkerd.io > tests/gen.rs
echo "pub type CR = Server;" >> tests/gen.rs
kubectl apply -f tests/server.yaml
cargo test --test runner -- --nocapture
Expand Down
6 changes: 5 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,10 @@ struct Kopium {
schema: String,

/// Derive these extra traits on generated structs
#[structopt(long, possible_values = &["Copy", "Default", "PartialEq", "Eq", "PartialOrd", "Ord", "Hash", "JsonSchema"])]
#[structopt(long,
short = "D",
possible_values = &["Copy", "Default", "PartialEq", "Eq", "PartialOrd", "Ord", "Hash", "JsonSchema"],
)]
derive: Vec<String>,

#[structopt(subcommand)]
Expand Down Expand Up @@ -266,6 +269,7 @@ impl Kopium {
}
println!("pub struct {} {{", s.name);
} else {
self.print_derives();
println!("#[derive(Serialize, Deserialize, Clone, Debug)]");
let spec_trimmed_name = s.name.as_str().replace(&format!("{}Spec", kind), &kind);
println!("pub struct {} {{", spec_trimmed_name);
Expand Down

0 comments on commit 10e6b01

Please sign in to comment.