[GH-ISSUE #211] Custom UnmarshalJSON for VirtualMachineConfig to Avoid Duplicate Device Fields #60

Open
opened 2026-03-03 15:29:56 +03:00 by kerem · 1 comment
Owner

Originally created by @samuelemusiani on GitHub (Aug 26, 2025).
Original GitHub issue: https://github.com/luthermonson/go-proxmox/issues/211

Hi, I have a feature request: creating a custom UnmarshalJSON for the VirtualMachineConfig type.

Currently, the VirtualMachineConfig struct contains many duplicate fields for devices such as Net0, Net1, ..., and similar patterns for disks and other resources. This design is not ideal because it limits the number of resources on the VM. (Currently I can't have more than 10 network interfaces on the same VM).

I want to implement the func (vc *VirtualMachineConfig) UnmarshalJSON(data []byte) error method that will:

  • Parse all sequentially-numbered fields (e.g., Net0, Net1, ...) directly into their respective map fields (e.g., Nets).
  • Avoid populating the individual fields for each device (Net0, Net1, ...) and instead keep all data inside the map, reducing duplication and making the struct easier to maintain and extend.

I think that for a more clean code the numbered fields can be deleted, but this could be a breaking change.

Example

Instead of unmarshalling:

{
  "net0": "virtio=XX:XX:XX:XX:XX:XX,bridge=vmbr0",
  "net1": "virtio=YY:YY:YY:YY:YY:YY,bridge=vmbr1"
}

Into fields Net0, Net1, ..., the custom unmarshaller should populate:

Nets["net0"] = "virtio=XX:XX:XX:XX:XX:XX,bridge=vmbr0"
Nets["net1"] = "virtio=YY:YY:YY:YY:YY:YY,bridge=vmbr1"

And avoid the individual fields within the struct.

I can implement this.

I've also noticed that it exists a custom unmarshalig method for the ContainerConfig type that fills partially the maps inside the struct, but at the moment for the VirtualMachineConfig type this method does not exists so all the maps are always empty.

Originally created by @samuelemusiani on GitHub (Aug 26, 2025). Original GitHub issue: https://github.com/luthermonson/go-proxmox/issues/211 Hi, I have a feature request: creating a custom UnmarshalJSON for the VirtualMachineConfig type. Currently, the `VirtualMachineConfig` struct contains many duplicate fields for devices such as `Net0`, `Net1`, ..., and similar patterns for disks and other resources. This design is not ideal because it limits the number of resources on the VM. (Currently I can't have more than 10 network interfaces on the same VM). I want to implement the `func (vc *VirtualMachineConfig) UnmarshalJSON(data []byte) error` method that will: - Parse all sequentially-numbered fields (e.g., `Net0`, `Net1`, ...) directly into their respective map fields (e.g., `Nets`). - Avoid populating the individual fields for each device (`Net0`, `Net1`, ...) and instead keep all data inside the map, reducing duplication and making the struct easier to maintain and extend. I think that for a more clean code the numbered fields can be deleted, but this could be a breaking change. ### Example Instead of unmarshalling: ```json { "net0": "virtio=XX:XX:XX:XX:XX:XX,bridge=vmbr0", "net1": "virtio=YY:YY:YY:YY:YY:YY,bridge=vmbr1" } ``` Into fields `Net0`, `Net1`, ..., the custom unmarshaller should populate: ```go Nets["net0"] = "virtio=XX:XX:XX:XX:XX:XX,bridge=vmbr0" Nets["net1"] = "virtio=YY:YY:YY:YY:YY:YY,bridge=vmbr1" ``` And avoid the individual fields within the struct. I can implement this. I've also noticed that it exists a custom unmarshalig method for the ContainerConfig type that fills partially the maps inside the struct, but at the moment for the VirtualMachineConfig type this method does not exists so all the maps are always empty.
Author
Owner

@samuelemusiani commented on GitHub (Aug 26, 2025):

For example if vc is the virtualMachine config this could parse all the network interfaces:

	var tmpMap map[string]any
	if err := json.Unmarshal(data, &tmpMap); err != nil {
		return err
	}

	for k, v := range tmpMap {
		if strings.HasPrefix(k, "net") {
			vc.Nets[k] = v.(string)
		}
	}

A similar thing must be done on all the other fields (SCSI, SATA, USBs, ecc.)

<!-- gh-comment-id:3224739527 --> @samuelemusiani commented on GitHub (Aug 26, 2025): For example if `vc` is the virtualMachine config this could parse all the network interfaces: ```go var tmpMap map[string]any if err := json.Unmarshal(data, &tmpMap); err != nil { return err } for k, v := range tmpMap { if strings.HasPrefix(k, "net") { vc.Nets[k] = v.(string) } } ``` A similar thing must be done on all the other fields (SCSI, SATA, USBs, ecc.)
Sign in to join this conversation.
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/go-proxmox#60
No description provided.