[pdm-devel] [PATCH proxmox-datacenter-manager v2 1/4] pdm-api-types: add firewall status types
Lukas Wagner
l.wagner at proxmox.com
Fri Nov 7 13:27:08 CET 2025
2 small nits inline, but other than that:
Reviewed-by: Lukas Wagner <l.wagner at proxmox.com>
Tested-by: Lukas Wagner <l.wagner at proxmox.com>
On Wed Nov 5, 2025 at 5:35 PM CET, Hannes Laimer wrote:
> These types are returned by all the `../firewall/status` endpoints. The
> UI also uses them.
>
> Signed-off-by: Hannes Laimer <h.laimer at proxmox.com>
> ---
> lib/pdm-api-types/src/firewall.rs | 171 ++++++++++++++++++++++++++++++
> lib/pdm-api-types/src/lib.rs | 2 +
> 2 files changed, 173 insertions(+)
> create mode 100644 lib/pdm-api-types/src/firewall.rs
>
> diff --git a/lib/pdm-api-types/src/firewall.rs b/lib/pdm-api-types/src/firewall.rs
> new file mode 100644
> index 0000000..10357ad
> --- /dev/null
> +++ b/lib/pdm-api-types/src/firewall.rs
> @@ -0,0 +1,171 @@
> +use proxmox_schema::{api, Schema};
> +use serde::{Deserialize, Serialize};
> +
> +use crate::remotes::REMOTE_ID_SCHEMA;
> +use crate::{NODE_SCHEMA, VMID_SCHEMA};
> +
> +const FIREWALL_RULES_COUNT: Schema =
> + proxmox_schema::IntegerSchema::new("The total amount of rules present")
> + .minimum(0)
> + .schema();
> +
> +const FIREWALL_ACTIVE_RULES_COUNT: Schema =
> + proxmox_schema::IntegerSchema::new("The amount of enabled rules")
> + .minimum(0)
> + .schema();
> +
> +#[api(
> + properties: {
> + all: {
> + schema: FIREWALL_RULES_COUNT,
> + },
> + active: {
> + schema: FIREWALL_ACTIVE_RULES_COUNT,
> + }
> + }
> +)]
> +/// Count of all rules present and count of all enabled firewall rules.
> +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
> +pub struct RuleStat {
> + pub all: usize,
> + pub active: usize,
> +}
Could make sense to add 'serde(rename_all = "kebab-case")' even if you
don't need it right now, but just to avoid forgetting it in the future
when you or somebody else adds new members to the struct.
No need to send a new version for this alone though, can happen in a follow-up
patch.
> +
> +#[api(
> + properties: {
> + enabled: {
> + type: bool,
> + description: "True if the firewall is enabled",
> + },
> + rules: {
> + type: RuleStat,
> + flatten: true,
> + },
> + }
> +)]
> +/// Firewall status.
> +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
> +#[serde(rename_all = "kebab-case")]
> +pub struct FirewallStatus {
> + pub enabled: bool,
> + #[serde(flatten)]
> + pub rules: RuleStat,
> +}
> +
> +#[api(
> + properties: {
> + remote: {
> + schema: REMOTE_ID_SCHEMA,
> + },
> + status: {
> + type: FirewallStatus,
> + optional: true,
> + },
> + nodes: {
> + description: "Nodes in the cluster",
> + items: {
> + type: NodeFirewallStatus
> + },
> + type: Array,
> + },
> + }
> +)]
> +/// Firewall status of a PVE remote.
> +#[derive(Serialize, Deserialize, Clone, PartialEq)]
> +#[serde(rename_all = "kebab-case")]
> +pub struct RemoteFirewallStatus {
> + pub remote: String,
> + pub status: Option<FirewallStatus>,
> + pub nodes: Vec<NodeFirewallStatus>,
> +}
> +
> +#[api(
> + properties: {
> + node: {
> + schema: NODE_SCHEMA,
> + },
> + status: {
> + type: FirewallStatus,
> + optional: true,
> + },
> + guests: {
> + description: "Guests on a node",
> + items: {
> + type: GuestFirewallStatus
> + },
> + type: Array,
> + },
> + }
> +)]
> +/// Firewall status of a node
> +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
> +pub struct NodeFirewallStatus {
> + pub node: String,
> + pub status: Option<FirewallStatus>,
> + pub guests: Vec<GuestFirewallStatus>,
> +}
Same here.
> +
> +#[api]
> +#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq)]
> +#[serde(rename_all = "lowercase")]
> +/// The type of the guest
> +pub enum GuestKind {
> + /// Guest is a LXC
> + Lxc,
> + /// Guets is a QEMU
> + Qemu,
> +}
> +
> +impl GuestKind {
> + pub const fn as_str(&self) -> &'static str {
> + match self {
> + GuestKind::Lxc => "lxc",
> + GuestKind::Qemu => "qemu",
> + }
> + }
> +}
> +
> +impl AsRef<str> for GuestKind {
> + fn as_ref(&self) -> &str {
> + self.as_str()
> + }
> +}
> +
> +impl From<GuestKind> for &'static str {
> + fn from(kind: GuestKind) -> Self {
> + kind.as_str()
> + }
> +}
> +
> +impl From<&GuestKind> for &'static str {
> + fn from(kind: &GuestKind) -> Self {
> + kind.as_str()
> + }
> +}
> +
> +#[api(
> + properties: {
> + vmid: {
> + schema: VMID_SCHEMA,
> + },
> + name: {
> + type: String,
> + description: "Name of the guest.",
> + },
> + status: {
> + type: FirewallStatus,
> + optional: true,
> + },
> + kind: {
> + type: GuestKind,
> + }
> + }
> +)]
> +/// Firewall status of a guest
> +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
> +pub struct GuestFirewallStatus {
> + pub vmid: u32,
> + pub name: String,
> + pub status: Option<FirewallStatus>,
> + pub kind: GuestKind,
> +}
> diff --git a/lib/pdm-api-types/src/lib.rs b/lib/pdm-api-types/src/lib.rs
> index ee4dfb2..78a9fa5 100644
> --- a/lib/pdm-api-types/src/lib.rs
> +++ b/lib/pdm-api-types/src/lib.rs
> @@ -94,6 +94,8 @@ pub use proxmox_schema::upid::*;
> mod openid;
> pub use openid::*;
>
> +pub mod firewall;
> +
> pub mod remotes;
>
> pub mod remote_updates;
More information about the pdm-devel
mailing list