use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SigningCeremonySpec {
pub scheme: String,
pub threshold: u32,
#[serde(rename = "partyCount")]
pub party_count: u32,
#[serde(rename = "messageRef")]
pub message_ref: ConfigMapRef,
#[serde(rename = "outputRef")]
pub output_ref: SecretRef,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConfigMapRef {
pub config_map: String,
pub key: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SecretRef {
pub secret: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SigningCeremonyStatus {
pub phase: CeremonyPhase,
pub started_at: Option<String>,
pub completed_at: Option<String>,
pub signature_secret: Option<String>,
pub error: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum CeremonyPhase {
Pending,
KeygenRunning,
Signing,
Completed,
Failed,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SigningCeremony {
#[serde(rename = "apiVersion")]
pub api_version: String,
pub kind: String,
pub metadata: ObjectMeta,
pub spec: SigningCeremonySpec,
pub status: Option<SigningCeremonyStatus>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ObjectMeta {
pub name: String,
pub namespace: Option<String>,
#[serde(default)]
pub labels: std::collections::BTreeMap<String, String>,
}
pub fn crd_yaml() -> String {
r#"apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: confiumsigningceremonies.confium.org
spec:
group: confium.org
names:
kind: ConfiumSigningCeremony
listKind: ConfiumSigningCeremonyList
plural: confiumsigningceremonies
singular: confiumsigningceremony
scope: Namespaced
versions:
- name: v1alpha1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
required: [scheme, threshold, partyCount]
properties:
scheme:
type: string
enum: [cmp20, gg18]
threshold:
type: integer
minimum: 1
partyCount:
type: integer
minimum: 1
messageRef:
type: object
properties:
configMap: { type: string }
key: { type: string }
outputRef:
type: object
properties:
secret: { type: string }
status:
type: object
properties:
phase:
type: string
enum: [pending, keygenrunning, signing, completed, failed]
startedAt: { type: string }
completedAt: { type: string }
signatureSecret: { type: string }
error: { type: string }
"#
.to_string()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn crd_yaml_is_valid_yaml() {
let yaml = crd_yaml();
let parsed: serde_yaml::Value = serde_yaml::from_str(&yaml).expect("CRD YAML must parse");
assert_eq!(parsed["kind"], "CustomResourceDefinition");
}
#[test]
fn ceremony_spec_round_trips() {
let spec = SigningCeremonySpec {
scheme: "cmp20".to_string(),
threshold: 3,
party_count: 5,
message_ref: ConfigMapRef {
config_map: "release-artifact".to_string(),
key: "release.tar.gz".to_string(),
},
output_ref: SecretRef {
secret: "release-signature".to_string(),
},
};
let json = serde_json::to_string(&spec).unwrap();
let parsed: SigningCeremonySpec = serde_json::from_str(&json).unwrap();
assert_eq!(parsed.scheme, "cmp20");
assert_eq!(parsed.threshold, 3);
}
}