feat(models): implement typed response models for PVE 8.x and 9.x

Add C# model classes for all PVE API resources: nodes, VMs, VM config,
containers, storage, network interfaces, SDN zones/vnets, users, roles,
permissions, snapshots, tasks, and cluster status. All models use dual
JSON attributes (System.Text.Json + Newtonsoft.Json), nullable optional
fields, and human-readable ToString() overrides.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Clint Branham
2026-03-17 15:45:06 -05:00
parent 2c7e90d185
commit 4ac38f7714
20 changed files with 2085 additions and 0 deletions
@@ -0,0 +1,130 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace PSProxmoxVE.Core.Models.Network;
/// <summary>
/// Represents a network interface configuration on a Proxmox VE node,
/// as returned by the /nodes/{node}/network endpoint.
/// </summary>
public class PveNetwork
{
/// <summary>
/// The interface name (e.g., "vmbr0", "eth0", "bond0").
/// </summary>
[JsonPropertyName("iface")]
[JsonProperty("iface")]
public string Iface { get; set; } = string.Empty;
/// <summary>
/// The interface type (e.g., "bridge", "bond", "eth", "vlan", "OVSBridge").
/// </summary>
[JsonPropertyName("type")]
[JsonProperty("type")]
public string? Type { get; set; }
/// <summary>
/// The IPv4 address assigned to this interface.
/// </summary>
[JsonPropertyName("address")]
[JsonProperty("address")]
public string? Address { get; set; }
/// <summary>
/// The IPv4 netmask for this interface.
/// </summary>
[JsonPropertyName("netmask")]
[JsonProperty("netmask")]
public string? Netmask { get; set; }
/// <summary>
/// The IPv4 default gateway associated with this interface.
/// </summary>
[JsonPropertyName("gateway")]
[JsonProperty("gateway")]
public string? Gateway { get; set; }
/// <summary>
/// Space-separated list of physical ports attached to this bridge.
/// </summary>
[JsonPropertyName("bridge_ports")]
[JsonProperty("bridge_ports")]
public string? BridgePorts { get; set; }
/// <summary>
/// Space-separated list of slave interfaces for bond/team interfaces.
/// </summary>
[JsonPropertyName("slaves")]
[JsonProperty("slaves")]
public string? BondSlaves { get; set; }
/// <summary>
/// VLAN ID for VLAN sub-interfaces.
/// </summary>
[JsonPropertyName("vlan-id")]
[JsonProperty("vlan-id")]
public int? VlanId { get; set; }
/// <summary>
/// The Maximum Transmission Unit in bytes.
/// </summary>
[JsonPropertyName("mtu")]
[JsonProperty("mtu")]
public int? Mtu { get; set; }
/// <summary>
/// Indicates whether the interface is brought up automatically at boot (1) or not (0).
/// </summary>
[JsonPropertyName("autostart")]
[JsonProperty("autostart")]
public int? Autostart { get; set; }
/// <summary>
/// Indicates whether the interface is currently active/up (1) or down (0).
/// </summary>
[JsonPropertyName("active")]
[JsonProperty("active")]
public int? Active { get; set; }
/// <summary>
/// Optional comment or description for this interface.
/// </summary>
[JsonPropertyName("comments")]
[JsonProperty("comments")]
public string? Comments { get; set; }
/// <summary>
/// IPv4 address in CIDR notation (e.g., "192.168.1.1/24").
/// </summary>
[JsonPropertyName("cidr")]
[JsonProperty("cidr")]
public string? Cidr { get; set; }
/// <summary>
/// Indicates whether VLAN-aware bridging is enabled on this bridge (1) or not (0).
/// </summary>
[JsonPropertyName("bridge_vlan_aware")]
[JsonProperty("bridge_vlan_aware")]
public int? BridgeVlanAware { get; set; }
/// <summary>
/// The bonding mode for bond interfaces (e.g., "active-backup", "802.3ad", "balance-rr").
/// </summary>
[JsonPropertyName("bond_mode")]
[JsonProperty("bond_mode")]
public string? BondMode { get; set; }
/// <summary>
/// The node this network interface belongs to. Populated by cmdlets after retrieval.
/// </summary>
public string? Node { get; set; }
/// <inheritdoc />
public override string ToString()
{
var addr = Cidr ?? Address ?? "N/A";
var activeStr = Active is 1 ? "up" : "down";
return $"Network: {Iface} | Type: {Type ?? "N/A"} | Address: {addr} | "
+ $"GW: {Gateway ?? "N/A"} | MTU: {Mtu?.ToString() ?? "N/A"} | {activeStr}";
}
}
@@ -0,0 +1,62 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace PSProxmoxVE.Core.Models.Network;
/// <summary>
/// Represents a Software-Defined Networking (SDN) virtual network (VNet) as returned by
/// the /cluster/sdn/vnets endpoint.
/// Available in Proxmox VE 8.0+.
/// </summary>
public class PveSdnVnet
{
/// <summary>
/// The unique VNet identifier.
/// </summary>
[JsonPropertyName("vnet")]
[JsonProperty("vnet")]
public string Vnet { get; set; } = string.Empty;
/// <summary>
/// The SDN zone this VNet belongs to.
/// </summary>
[JsonPropertyName("zone")]
[JsonProperty("zone")]
public string? Zone { get; set; }
/// <summary>
/// The VLAN or VXLAN tag associated with this VNet.
/// </summary>
[JsonPropertyName("tag")]
[JsonProperty("tag")]
public int? Tag { get; set; }
/// <summary>
/// An optional human-readable alias for this VNet.
/// </summary>
[JsonPropertyName("alias")]
[JsonProperty("alias")]
public string? Alias { get; set; }
/// <summary>
/// Indicates whether VLAN-aware mode is enabled on this VNet (1) or not (0).
/// </summary>
[JsonPropertyName("vlanaware")]
[JsonProperty("vlanaware")]
public int? VlanAware { get; set; }
/// <summary>
/// Optional comment or description for this SDN VNet.
/// </summary>
[JsonPropertyName("comments")]
[JsonProperty("comments")]
public string? Comments { get; set; }
/// <inheritdoc />
public override string ToString()
{
var vlanAwareStr = VlanAware is 1 ? " [vlan-aware]" : string.Empty;
return $"SDN VNet: {Vnet}{vlanAwareStr} | Zone: {Zone ?? "N/A"} | "
+ $"Tag: {Tag?.ToString() ?? "N/A"} | Alias: {Alias ?? "N/A"}";
}
}
@@ -0,0 +1,90 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace PSProxmoxVE.Core.Models.Network;
/// <summary>
/// Represents a Software-Defined Networking (SDN) zone as returned by
/// the /cluster/sdn/zones endpoint.
/// Available in Proxmox VE 8.0+.
/// </summary>
public class PveSdnZone
{
/// <summary>
/// The unique zone identifier.
/// </summary>
[JsonPropertyName("zone")]
[JsonProperty("zone")]
public string Zone { get; set; } = string.Empty;
/// <summary>
/// The zone type (e.g., "simple", "vlan", "qinq", "vxlan", "evpn").
/// </summary>
[JsonPropertyName("type")]
[JsonProperty("type")]
public string? Type { get; set; }
/// <summary>
/// The DNS server address associated with this zone.
/// </summary>
[JsonPropertyName("dns")]
[JsonProperty("dns")]
public string? Dns { get; set; }
/// <summary>
/// The reverse DNS zone name for this SDN zone.
/// </summary>
[JsonPropertyName("reversedns")]
[JsonProperty("reversedns")]
public string? Reversedns { get; set; }
/// <summary>
/// The DNS zone name used for forward lookups.
/// </summary>
[JsonPropertyName("dnszone")]
[JsonProperty("dnszone")]
public string? DnsZone { get; set; }
/// <summary>
/// The IPAM plugin to use for IP address management in this zone.
/// </summary>
[JsonPropertyName("ipam")]
[JsonProperty("ipam")]
public string? Ipam { get; set; }
/// <summary>
/// The Maximum Transmission Unit in bytes for this zone.
/// </summary>
[JsonPropertyName("mtu")]
[JsonProperty("mtu")]
public int? Mtu { get; set; }
/// <summary>
/// Comma-separated list of nodes that participate in this SDN zone.
/// </summary>
[JsonPropertyName("nodes")]
[JsonProperty("nodes")]
public string? Nodes { get; set; }
/// <summary>
/// Indicates whether the zone has pending (unapplied) configuration changes (1) or not (0).
/// </summary>
[JsonPropertyName("pending")]
[JsonProperty("pending")]
public int? Pending { get; set; }
/// <summary>
/// Optional comment or description for this SDN zone.
/// </summary>
[JsonPropertyName("comments")]
[JsonProperty("comments")]
public string? Comments { get; set; }
/// <inheritdoc />
public override string ToString()
{
var pendingStr = Pending is 1 ? " [pending]" : string.Empty;
return $"SDN Zone: {Zone}{pendingStr} | Type: {Type ?? "N/A"} | DNS: {Dns ?? "N/A"} | "
+ $"IPAM: {Ipam ?? "N/A"} | Nodes: {Nodes ?? "all"}";
}
}