using System; using System.Collections.Generic; using System.Linq; namespace PSProxmox.Models { /// /// Builder for creating virtual machine configurations in Proxmox VE. /// public class ProxmoxVMBuilder { private readonly Dictionary _parameters = new Dictionary(); private readonly List _networkInterfaces = new List(); private readonly List _disks = new List(); private readonly List _serialPorts = new List(); private readonly List _usbDevices = new List(); private readonly List _pciDevices = new List(); /// /// Gets or sets the name of the VM. /// public string Name { get; set; } /// /// Gets or sets the VM ID. /// public int? VMID { get; set; } /// /// Gets or sets the node where the VM will be created. /// public string Node { get; set; } /// /// Gets or sets the description of the VM. /// public string Description { get; set; } /// /// Gets or sets the tags for the VM. /// public string Tags { get; set; } /// /// Gets or sets the memory in MB. /// public int Memory { get; set; } = 512; /// /// Gets or sets the number of CPU cores. /// public int Cores { get; set; } = 1; /// /// Gets or sets the CPU type. /// public string CPUType { get; set; } = "host"; /// /// Gets or sets the operating system type. /// public string OSType { get; set; } = "l26"; // Linux 2.6+ /// /// Gets or sets a value indicating whether to start the VM after creation. /// public bool Start { get; set; } /// /// Gets or sets the IP pool to use for assigning an IP address. /// public string IPPool { get; set; } /// /// Initializes a new instance of the class. /// /// The name of the VM. public ProxmoxVMBuilder(string name) { Name = name ?? throw new ArgumentNullException(nameof(name)); } /// /// Sets the VM ID. /// /// The VM ID. /// The builder instance. public ProxmoxVMBuilder WithVMID(int vmid) { VMID = vmid; return this; } /// /// Sets the node where the VM will be created. /// /// The node name. /// The builder instance. public ProxmoxVMBuilder WithNode(string node) { Node = node ?? throw new ArgumentNullException(nameof(node)); return this; } /// /// Sets the description of the VM. /// /// The description. /// The builder instance. public ProxmoxVMBuilder WithDescription(string description) { Description = description; return this; } /// /// Sets the tags for the VM. /// /// The tags. /// The builder instance. public ProxmoxVMBuilder WithTags(params string[] tags) { Tags = string.Join(",", tags); return this; } /// /// Sets the memory for the VM. /// /// The memory in MB. /// The builder instance. public ProxmoxVMBuilder WithMemory(int memoryMB) { if (memoryMB <= 0) { throw new ArgumentException("Memory must be greater than 0", nameof(memoryMB)); } Memory = memoryMB; return this; } /// /// Sets the number of CPU cores for the VM. /// /// The number of cores. /// The builder instance. public ProxmoxVMBuilder WithCores(int cores) { if (cores <= 0) { throw new ArgumentException("Cores must be greater than 0", nameof(cores)); } Cores = cores; return this; } /// /// Sets the CPU type for the VM. /// /// The CPU type. /// The builder instance. public ProxmoxVMBuilder WithCPUType(string cpuType) { CPUType = cpuType ?? throw new ArgumentNullException(nameof(cpuType)); return this; } /// /// Sets the operating system type for the VM. /// /// The OS type. /// The builder instance. public ProxmoxVMBuilder WithOSType(string osType) { OSType = osType ?? throw new ArgumentNullException(nameof(osType)); return this; } /// /// Sets whether to start the VM after creation. /// /// Whether to start the VM. /// The builder instance. public ProxmoxVMBuilder WithStart(bool start) { Start = start; return this; } /// /// Sets the IP pool to use for assigning an IP address. /// /// The IP pool name. /// The builder instance. public ProxmoxVMBuilder WithIPPool(string ipPool) { IPPool = ipPool; return this; } /// /// Adds a disk to the VM. /// /// The disk size in GB. /// The storage location. /// The disk format. /// The disk bus. /// The builder instance. public ProxmoxVMBuilder WithDisk(int sizeGB, string storage, string format = "raw", string bus = "virtio") { if (sizeGB <= 0) { throw new ArgumentException("Size must be greater than 0", nameof(sizeGB)); } if (string.IsNullOrEmpty(storage)) { throw new ArgumentNullException(nameof(storage)); } string diskId = $"scsi{_disks.Count}"; _disks.Add($"{diskId}={storage}:{sizeGB},format={format}"); return this; } /// /// Adds a network interface to the VM. /// /// The network model. /// The network bridge. /// The VLAN ID. /// The MAC address. /// The builder instance. public ProxmoxVMBuilder WithNetwork(string model = "virtio", string bridge = "vmbr0", int? vlan = null, string macAddress = null) { if (string.IsNullOrEmpty(model)) { throw new ArgumentNullException(nameof(model)); } if (string.IsNullOrEmpty(bridge)) { throw new ArgumentNullException(nameof(bridge)); } string netId = $"net{_networkInterfaces.Count}"; string netConfig = $"{model},bridge={bridge}"; if (vlan.HasValue) { netConfig += $",tag={vlan.Value}"; } if (!string.IsNullOrEmpty(macAddress)) { netConfig += $",macaddr={macAddress}"; } _networkInterfaces.Add($"{netId}={netConfig}"); return this; } /// /// Adds a static IP configuration to the VM. /// /// The IP address with CIDR notation. /// The gateway address. /// The network interface index. /// The builder instance. public ProxmoxVMBuilder WithIPConfig(string ipAddress, string gateway, int networkIndex = 0) { if (string.IsNullOrEmpty(ipAddress)) { throw new ArgumentNullException(nameof(ipAddress)); } if (string.IsNullOrEmpty(gateway)) { throw new ArgumentNullException(nameof(gateway)); } if (networkIndex < 0 || networkIndex >= _networkInterfaces.Count) { throw new ArgumentOutOfRangeException(nameof(networkIndex)); } string netId = $"net{networkIndex}"; string netConfig = _networkInterfaces[networkIndex].Split('=')[1]; _networkInterfaces[networkIndex] = $"{netId}={netConfig},ip={ipAddress},gw={gateway}"; return this; } /// /// Sets the boot order for the VM. /// /// The boot devices in order. /// The builder instance. public ProxmoxVMBuilder WithBootOrder(params string[] bootDevices) { if (bootDevices == null || bootDevices.Length == 0) { throw new ArgumentException("At least one boot device must be specified", nameof(bootDevices)); } _parameters["boot"] = string.Join(";", bootDevices); return this; } /// /// Sets the VGA type for the VM. /// /// The VGA type. /// The builder instance. public ProxmoxVMBuilder WithVGA(string vgaType) { if (string.IsNullOrEmpty(vgaType)) { throw new ArgumentNullException(nameof(vgaType)); } _parameters["vga"] = vgaType; return this; } /// /// Sets a custom parameter for the VM. /// /// The parameter name. /// The parameter value. /// The builder instance. public ProxmoxVMBuilder WithParameter(string name, string value) { if (string.IsNullOrEmpty(name)) { throw new ArgumentNullException(nameof(name)); } _parameters[name] = value; return this; } /// /// Builds the VM configuration parameters. /// /// The VM configuration parameters. public Dictionary Build() { var parameters = new Dictionary(_parameters); // Add basic parameters parameters["name"] = Name; parameters["memory"] = Memory.ToString(); parameters["cores"] = Cores.ToString(); parameters["cpu"] = CPUType; parameters["ostype"] = OSType; if (!string.IsNullOrEmpty(Description)) { parameters["description"] = Description; } if (!string.IsNullOrEmpty(Tags)) { parameters["tags"] = Tags; } // Add network interfaces for (int i = 0; i < _networkInterfaces.Count; i++) { string[] parts = _networkInterfaces[i].Split('='); parameters[parts[0]] = parts[1]; } // Add disks for (int i = 0; i < _disks.Count; i++) { string[] parts = _disks[i].Split('='); parameters[parts[0]] = parts[1]; } // Add serial ports for (int i = 0; i < _serialPorts.Count; i++) { string[] parts = _serialPorts[i].Split('='); parameters[parts[0]] = parts[1]; } // Add USB devices for (int i = 0; i < _usbDevices.Count; i++) { string[] parts = _usbDevices[i].Split('='); parameters[parts[0]] = parts[1]; } // Add PCI devices for (int i = 0; i < _pciDevices.Count; i++) { string[] parts = _pciDevices[i].Split('='); parameters[parts[0]] = parts[1]; } return parameters; } } }