use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct Empty {}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct Capabilities {
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub root_disk_grow: bool,
pub cpu_resize: bool,
pub memory_resize: bool,
pub secrets_update: bool,
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct MemoryState {
pub boot_mib: u64,
pub target_mib: u64,
pub current_mib: u64,
pub max_mib: u64,
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct CpuState {
pub possible: u32,
pub requested_online: u32,
pub actual_online: u32,
pub enforced: u32,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub struct MemoryTarget {
pub total_mib: u64,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub struct CpuTarget {
pub online: u32,
}
#[derive(Clone, Serialize, Deserialize, zeroize::Zeroize, zeroize::ZeroizeOnDrop)]
#[serde(transparent)]
pub struct SecretValue(pub String);
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "change", rename_all = "snake_case")]
pub enum SecretChange {
Rotate {
name: String,
value: SecretValue,
},
Remove {
name: String,
},
SetAllowedHosts {
name: String,
hosts: Vec<String>,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SecretsUpdate {
pub changes: Vec<SecretChange>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ErrorEffect {
None,
Unknown,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ControlError {
pub code: String,
pub message: String,
pub effect: ErrorEffect,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(tag = "outcome", rename_all = "snake_case")]
pub enum SecretsResult {
Complete {
applied_count: u32,
},
Failed {
applied_count: u32,
failed_index: u32,
error: ControlError,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "op", rename_all = "snake_case")]
pub enum ControlRequest {
Capabilities,
MemoryTarget {
total_mib: u64,
},
MemoryState,
CpuTarget {
online: u32,
},
CpuState,
SecretsUpdate {
changes: Vec<SecretChange>,
},
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct JsonControlResponse {
pub ok: bool,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub error: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub memory: Option<MemoryState>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub cpu: Option<CpuState>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub capabilities: Option<Capabilities>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub control_protocols: Option<Vec<String>>,
}
impl ControlError {
pub fn rejected(code: impl Into<String>, message: impl Into<String>) -> Self {
Self {
code: code.into(),
message: message.into(),
effect: ErrorEffect::None,
}
}
}
impl std::fmt::Debug for SecretValue {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str("[redacted]")
}
}