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;
}
}
}