diff --git a/proxmox/resource_lxc.go b/proxmox/resource_lxc.go index 4cd95f05..f157b531 100644 --- a/proxmox/resource_lxc.go +++ b/proxmox/resource_lxc.go @@ -232,6 +232,10 @@ func resourceLxc() *schema.Resource { Optional: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeInt, + Computed: true, + }, "name": { Type: schema.TypeString, Required: true, @@ -667,10 +671,28 @@ func resourceLxcUpdate(d *schema.ResourceData, meta interface{}) error { config.Unprivileged = d.Get("unprivileged").(bool) if d.HasChange("network") { - // TODO Delete extra networks - networks := d.Get("network").([]interface{}) - if len(networks) > 0 { - lxcNetworks := DevicesListToDevices(networks, "") + oldSet, newSet := d.GetChange("network") + oldNetworks := make([]map[string]interface{}, 0) + newNetworks := make([]map[string]interface{}, 0) + + // Convert from []interface{} to []map[string]interface{} + for _, network := range oldSet.([]interface{}) { + oldNetworks = append(oldNetworks, network.(map[string]interface{})) + } + for _, network := range newSet.([]interface{}) { + newNetworks = append(newNetworks, network.(map[string]interface{})) + } + + processLxcNetworkChanges(oldNetworks, newNetworks, pconf, vmr) + + if len(newNetworks) > 0 { + // Drop all the ids since they can't be sent to the API + newNetworks, _ = DropElementsFromMap([]string{"id"}, newNetworks) + // Convert from []map[string]interface{} to pxapi.QemuDevices + lxcNetworks := make(pxapi.QemuDevices, 0) + for index, network := range newNetworks { + lxcNetworks[index] = network + } config.Networks = lxcNetworks } } @@ -816,7 +838,6 @@ func _resourceLxcRead(d *schema.ResourceData, meta interface{}) error { return err } flatNetworks, _ := FlattenDevicesList(config.Networks) - flatNetworks, _ = DropElementsFromMap([]string{"id"}, flatNetworks) if err = d.Set("network", flatNetworks); err != nil { return err } @@ -1019,3 +1040,46 @@ func processDiskResize( } return nil } + +func processLxcNetworkChanges(prevNetworks []map[string]interface{}, newNetworks []map[string]interface{}, pconf *providerConfiguration, vmr *pxapi.VmRef) error { + delNetworks := make([]map[string]interface{}, 0) + + // Collect the IDs of networks that exist in `prevNetworks` but not in `newNetworks`. + for _, prevNet := range prevNetworks { + found := false + prevName := prevNet["id"].(int) + for _, newNet := range newNetworks { + newName := newNet["id"].(int) + if prevName == newName { + found = true + break + } + } + if !found { + delNetworks = append(delNetworks, prevNet) + } + } + + if len(delNetworks) > 0 { + deleteNetKeys := []string{} + for _, net := range delNetworks { + // Construct id that proxmox API expects (net+) + deleteNetKeys = append(deleteNetKeys, "net"+strconv.Itoa(net["id"].(int))) + } + + params := map[string]interface{}{ + "delete": strings.Join(deleteNetKeys, ", "), + } + if vmr.GetVmType() == "lxc" { + if _, err := pconf.Client.SetLxcConfig(vmr, params); err != nil { + return err + } + } else { + if _, err := pconf.Client.SetVmConfig(vmr, params); err != nil { + return err + } + } + } + + return nil +}