feat: add serialize and deserialize for manifest

This commit is contained in:
2026-01-06 12:38:25 +01:00
parent 353b8c1eb0
commit 2348c27d8b
6 changed files with 47 additions and 41 deletions

View File

@@ -3,7 +3,7 @@ use std::io::{BufRead, Write};
use async_trait::async_trait; use async_trait::async_trait;
use nocontrol::{ use nocontrol::{
manifests::{Manifest, ManifestMetadata, ManifestState}, manifests::{Manifest, ManifestMetadata, ManifestState},
Operator, Operator, Specification,
}; };
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tracing_subscriber::EnvFilter; use tracing_subscriber::EnvFilter;
@@ -163,11 +163,19 @@ impl Operator for MyOperator {
} }
} }
#[derive(Clone, Serialize)] #[derive(Clone, Serialize, Deserialize)]
pub enum Specifications { pub enum Specifications {
Deployment(DeploymentControllerManifest), Deployment(DeploymentControllerManifest),
} }
impl Specification for Specifications {
fn kind(&self) -> &'static str {
match self {
Specifications::Deployment(_) => "deployment",
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DeploymentControllerManifest { pub struct DeploymentControllerManifest {
name: String, name: String,

View File

@@ -1,5 +1,3 @@
use std::marker::PhantomData;
use tokio_util::sync::CancellationToken; use tokio_util::sync::CancellationToken;
use crate::{ use crate::{

View File

@@ -1,20 +1,22 @@
use std::sync::Arc; use std::sync::Arc;
use jiff::ToSpan; use jiff::ToSpan;
use serde::Serialize;
use sha2::{Digest, Sha256}; use sha2::{Digest, Sha256};
use tokio::sync::RwLock; use tokio::sync::RwLock;
use crate::manifests::{ use crate::{
Manifest, ManifestLease, ManifestState, ManifestStatus, ManifestStatusState, WorkerId, manifests::{
Manifest, ManifestLease, ManifestState, ManifestStatus, ManifestStatusState, WorkerId,
},
Specification,
}; };
#[derive(Clone)] #[derive(Clone)]
pub struct BackingStore<T: Clone + Serialize> { pub struct BackingStore<T: Specification> {
manifests: Arc<RwLock<Vec<ManifestState<T>>>>, manifests: Arc<RwLock<Vec<ManifestState<T>>>>,
} }
impl<T: Clone + Serialize> BackingStore<T> { impl<T: Specification> BackingStore<T> {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
manifests: Arc::new(RwLock::new(Vec::new())), manifests: Arc::new(RwLock::new(Vec::new())),

View File

@@ -2,13 +2,17 @@ mod control_plane;
pub mod manifests; pub mod manifests;
pub use control_plane::ControlPlane; pub use control_plane::ControlPlane;
use serde::Serialize; use serde::{de::DeserializeOwned, Serialize};
use crate::manifests::{Manifest, ManifestState}; use crate::manifests::ManifestState;
pub trait Specification: Clone + Serialize + DeserializeOwned {
fn kind(&self) -> &'static str;
}
#[async_trait::async_trait] #[async_trait::async_trait]
pub trait Operator { pub trait Operator {
type Specifications: Clone + Serialize; type Specifications: Specification;
async fn reconcile( async fn reconcile(
&self, &self,

View File

@@ -1,7 +1,13 @@
use serde::{Deserialize, Serialize}; use serde::{de::DeserializeOwned, Deserialize, Serialize};
use crate::Specification;
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ManifestState<T: Clone> { #[serde(bound(serialize = "T: Serialize", deserialize = "T: DeserializeOwned"))]
pub struct ManifestState<T>
where
T: Specification,
{
pub manifest: Manifest<T>, pub manifest: Manifest<T>,
pub manifest_hash: Vec<u8>, pub manifest_hash: Vec<u8>,
pub generation: u64, pub generation: u64,
@@ -22,7 +28,11 @@ pub struct ManifestLease {
} }
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Manifest<T> { #[serde(bound(serialize = "T: Serialize", deserialize = "T: DeserializeOwned"))]
pub struct Manifest<T>
where
T: Specification,
{
pub name: String, pub name: String,
pub metadata: ManifestMetadata, pub metadata: ManifestMetadata,
pub spec: T, pub spec: T,
@@ -53,27 +63,3 @@ pub struct ManifestEvent {
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ManifestMetadata {} pub struct ManifestMetadata {}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "@type")]
pub enum ManifestSpecification {
SchemaApplication {},
}
#[cfg(test)]
mod test {
use crate::manifests::*;
#[test]
fn manifest() -> anyhow::Result<()> {
let manifest = Manifest {
name: "ingest".into(),
metadata: ManifestMetadata {},
spec: ManifestSpecification::SchemaApplication {},
};
insta::assert_debug_snapshot!(manifest);
Ok(())
}
}

View File

@@ -1,7 +1,7 @@
use async_trait::async_trait; use async_trait::async_trait;
use nocontrol::{ use nocontrol::{
manifests::{Manifest, ManifestMetadata, ManifestState}, manifests::{Manifest, ManifestMetadata, ManifestState},
Operator, Operator, Specification,
}; };
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tracing_test::traced_test; use tracing_test::traced_test;
@@ -80,11 +80,19 @@ impl Operator for MyOperator {
} }
} }
#[derive(Clone, Serialize)] #[derive(Clone, Serialize, Deserialize)]
pub enum Specifications { pub enum Specifications {
Deployment(DeploymentControllerManifest), Deployment(DeploymentControllerManifest),
} }
impl Specification for Specifications {
fn kind(&self) -> &'static str {
match self {
Specifications::Deployment(_) => "deployment",
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DeploymentControllerManifest { pub struct DeploymentControllerManifest {
name: String, name: String,