diff --git a/pbs-api-types/src/lib.rs b/pbs-api-types/src/lib.rs index 460c7da7..6bae4a52 100644 --- a/pbs-api-types/src/lib.rs +++ b/pbs-api-types/src/lib.rs @@ -155,6 +155,9 @@ pub use zfs::*; mod metrics; pub use metrics::*; +mod version; +pub use version::*; + const_regex! { // just a rough check - dummy acceptor is used before persisting pub OPENSSL_CIPHERS_REGEX = r"^[0-9A-Za-z_:, +!\-@=.]+$"; diff --git a/pbs-api-types/src/version.rs b/pbs-api-types/src/version.rs new file mode 100644 index 00000000..7a4c6cb7 --- /dev/null +++ b/pbs-api-types/src/version.rs @@ -0,0 +1,88 @@ +//! Defines the types for the api version info endpoint +use std::convert::TryFrom; + +use anyhow::{format_err, Context}; + +use proxmox_schema::api; + +#[api( + description: "Api version information", + properties: { + "version": { + description: "Version 'major.minor'", + type: String, + }, + "release": { + description: "Version release", + type: String, + }, + "repoid": { + description: "Version repository id", + type: String, + }, + "features": { + description: "List of supported features", + type: Array, + items: { + type: String, + description: "Feature id", + }, + }, + } +)] +#[derive(serde::Deserialize, serde::Serialize)] +pub struct ApiVersionInfo { + pub version: String, + pub release: String, + pub repoid: String, + #[serde(default, skip_serializing_if = "Vec::is_empty")] + pub features: Vec, +} + +pub type ApiVersionMajor = u64; +pub type ApiVersionMinor = u64; +pub type ApiVersionRelease = u64; + +pub struct ApiVersion { + pub major: ApiVersionMajor, + pub minor: ApiVersionMinor, + pub release: ApiVersionRelease, + pub repoid: String, + pub features: Vec, +} + +impl TryFrom for ApiVersion { + type Error = anyhow::Error; + + fn try_from(value: ApiVersionInfo) -> Result { + let (major, minor) = value + .version + .split_once('.') + .ok_or_else(|| format_err!("malformed API version {}", value.version))?; + + let major: ApiVersionMajor = major + .parse() + .with_context(|| "failed to parse major version")?; + let minor: ApiVersionMinor = minor + .parse() + .with_context(|| "failed to parse minor version")?; + let release: ApiVersionRelease = value + .release + .parse() + .with_context(|| "failed to parse release version")?; + + Ok(Self { + major, + minor, + release, + repoid: value.repoid.clone(), + features: value.features.clone(), + }) + } +} + +impl ApiVersion { + pub fn supports_feature(&self, feature: &str) -> bool { + self.features.iter().any(|f| f == feature) + } +}