From c3d462e3904c5c8ad4b4fe2c6f4e9f66084ea8df Mon Sep 17 00:00:00 2001 From: Andreas Gruhler Date: Mon, 3 Jun 2019 09:01:19 +0200 Subject: [PATCH 01/14] add lxc resource --- examples/lxc_example.tf | 23 +++++++ proxmox/provider.go | 1 + proxmox/resource_lxc.go | 142 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 166 insertions(+) create mode 100644 examples/lxc_example.tf create mode 100644 proxmox/resource_lxc.go diff --git a/examples/lxc_example.tf b/examples/lxc_example.tf new file mode 100644 index 0000000..8587cef --- /dev/null +++ b/examples/lxc_example.tf @@ -0,0 +1,23 @@ +provider "proxmox" { + pm_tls_insecure = true + pm_api_url = "https://proxmox.org/api2/json" + pm_password = "supersecret" + pm_user = "terraform-user@pve" +} + +resource "proxmox_lxc" "lxc-test" { + hostname = "terraform-test-container" + ostemplate = "shared:vztmpl/centos-7-default_20171212_amd64.tar.xz" + target_node = "node-01" + networks = [ + { + name = "eth0" + bridge = "vmbr0" + ip = "dhcp" + ip6 = "dhcp" + } + ] + storage = "local-lvm" + pool = "terraform" + passsword = "rootroot" +} diff --git a/proxmox/provider.go b/proxmox/provider.go index 24bcb30..c829ddc 100644 --- a/proxmox/provider.go +++ b/proxmox/provider.go @@ -58,6 +58,7 @@ func Provider() *schema.Provider { ResourcesMap: map[string]*schema.Resource{ "proxmox_vm_qemu": resourceVmQemu(), + "proxmox_lxc": resourceLxc(), // TODO - storage_iso // TODO - bridge // TODO - vm_qemu_template diff --git a/proxmox/resource_lxc.go b/proxmox/resource_lxc.go new file mode 100644 index 0000000..2ebcaa8 --- /dev/null +++ b/proxmox/resource_lxc.go @@ -0,0 +1,142 @@ +package proxmox + +import ( + pxapi "github.com/Telmate/proxmox-api-go/proxmox" + "github.com/hashicorp/terraform/helper/schema" +) + +func resourceLxc() *schema.Resource { + *pxapi.Debug = true + return &schema.Resource{ + Create: resourceLxcCreate, + Read: resourceLxcRead, + Update: resourceLxcUpdate, + Delete: resourceLxcDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "hostname": { + Type: schema.TypeString, + Required: true, + }, + "target_node": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "ostemplate": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + "networks": &schema.Schema{ + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "bridge": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Default: "vmbr0", + }, + "ip": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Default: "dhcp", + }, + "ip6": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Default: "dhcp", + }, + }, + }, + }, + "storage": { + Type: schema.TypeString, + Optional: true, + Default: "local-lvm", + }, + "pool": { + Type: schema.TypeString, + Optional: true, + }, + "password": { + Type: schema.TypeString, + Optional: true, + }, + }, + } +} + +func resourceLxcCreate(d *schema.ResourceData, meta interface{}) error { + pconf := meta.(*providerConfiguration) + pmParallelBegin(pconf) + client := pconf.Client + vmName := d.Get("hostname").(string) + networks := d.Get("networks").(*schema.Set) + lxcNetworks := lxcDevicesSetToMap(networks) + + config := pxapi.ConfigLxc{ + Ostemplate: d.Get("ostemplate").(string), + Storage: d.Get("storage").(string), + Pool: d.Get("pool").(string), + Password: d.Get("password").(string), + Hostname: vmName, + Networks: lxcNetworks, + } + + targetNode := d.Get("target_node").(string) + //vmr, _ := client.GetVmRefByName(vmName) + + // get unique id + nextid, err := nextVmId(pconf) + if err != nil { + pmParallelEnd(pconf) + return err + } + vmr := pxapi.NewVmRef(nextid) + vmr.SetNode(targetNode) + err = config.CreateLxc(vmr, client) + if err != nil { + pmParallelEnd(pconf) + return err + } + + // The existence of a non-blank ID is what tells Terraform that a resource was created + d.SetId(resourceId(targetNode, "lxc", vmr.VmId())) + + return resourceLxcRead(d, meta) +} + +func resourceLxcUpdate(d *schema.ResourceData, meta interface{}) error { + return resourceLxcRead(d, meta) +} + +func resourceLxcRead(d *schema.ResourceData, meta interface{}) error { + return nil +} + +func resourceLxcDelete(d *schema.ResourceData, meta interface{}) error { + return nil +} + +func lxcDevicesSetToMap(devicesSet *schema.Set) pxapi.LxcDevices { + + devicesMap := pxapi.LxcDevices{} + + for _, set := range devicesSet.List() { + setMap, isMap := set.(map[string]interface{}) + if isMap { + setID := setMap["id"].(int) + devicesMap[setID] = setMap + } + } + return devicesMap +} From cde2db1bf84b6fe5d7a3d789bbaae10e4e7c401c Mon Sep 17 00:00:00 2001 From: Andreas Gruhler Date: Mon, 3 Jun 2019 09:16:32 +0200 Subject: [PATCH 02/14] fix password --- examples/lxc_example.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/lxc_example.tf b/examples/lxc_example.tf index 8587cef..e02ccc4 100644 --- a/examples/lxc_example.tf +++ b/examples/lxc_example.tf @@ -19,5 +19,5 @@ resource "proxmox_lxc" "lxc-test" { ] storage = "local-lvm" pool = "terraform" - passsword = "rootroot" + password = "rootroot" } From 92762171984c7879f304e7ab9238417f99514106 Mon Sep 17 00:00:00 2001 From: Andreas Gruhler Date: Wed, 5 Jun 2019 20:32:29 +0200 Subject: [PATCH 03/14] reuse device mapping functionality --- proxmox/resource_lxc.go | 36 +++++++++++++----------------------- proxmox/resource_vm_qemu.go | 12 ++++++------ 2 files changed, 19 insertions(+), 29 deletions(-) diff --git a/proxmox/resource_lxc.go b/proxmox/resource_lxc.go index 2ebcaa8..8becd25 100644 --- a/proxmox/resource_lxc.go +++ b/proxmox/resource_lxc.go @@ -71,6 +71,11 @@ func resourceLxc() *schema.Resource { Type: schema.TypeString, Optional: true, }, + "force": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, }, } } @@ -81,16 +86,15 @@ func resourceLxcCreate(d *schema.ResourceData, meta interface{}) error { client := pconf.Client vmName := d.Get("hostname").(string) networks := d.Get("networks").(*schema.Set) - lxcNetworks := lxcDevicesSetToMap(networks) + lxcNetworks := DevicesSetToMap(networks) - config := pxapi.ConfigLxc{ - Ostemplate: d.Get("ostemplate").(string), - Storage: d.Get("storage").(string), - Pool: d.Get("pool").(string), - Password: d.Get("password").(string), - Hostname: vmName, - Networks: lxcNetworks, - } + config := pxapi.NewConfigLxc() + config.Ostemplate = d.Get("ostemplate").(string) + config.Hostname = vmName + config.Networks = lxcNetworks + config.Password = d.Get("password").(string) + config.Pool = d.Get("pool").(string) + config.Storage = d.Get("storage").(string) targetNode := d.Get("target_node").(string) //vmr, _ := client.GetVmRefByName(vmName) @@ -126,17 +130,3 @@ func resourceLxcRead(d *schema.ResourceData, meta interface{}) error { func resourceLxcDelete(d *schema.ResourceData, meta interface{}) error { return nil } - -func lxcDevicesSetToMap(devicesSet *schema.Set) pxapi.LxcDevices { - - devicesMap := pxapi.LxcDevices{} - - for _, set := range devicesSet.List() { - setMap, isMap := set.(map[string]interface{}) - if isMap { - setID := setMap["id"].(int) - devicesMap[setID] = setMap - } - } - return devicesMap -} diff --git a/proxmox/resource_vm_qemu.go b/proxmox/resource_vm_qemu.go index c915af9..83267d0 100644 --- a/proxmox/resource_vm_qemu.go +++ b/proxmox/resource_vm_qemu.go @@ -354,9 +354,9 @@ func resourceVmQemuCreate(d *schema.ResourceData, meta interface{}) error { client := pconf.Client vmName := d.Get("name").(string) networks := d.Get("network").(*schema.Set) - qemuNetworks := devicesSetToMap(networks) + qemuNetworks := DevicesSetToMap(networks) disks := d.Get("disk").(*schema.Set) - qemuDisks := devicesSetToMap(disks) + qemuDisks := DevicesSetToMap(disks) config := pxapi.ConfigQemu{ Name: vmName, @@ -504,9 +504,9 @@ func resourceVmQemuUpdate(d *schema.ResourceData, meta interface{}) error { return err } configDisksSet := d.Get("disk").(*schema.Set) - qemuDisks := devicesSetToMap(configDisksSet) + qemuDisks := DevicesSetToMap(configDisksSet) configNetworksSet := d.Get("network").(*schema.Set) - qemuNetworks := devicesSetToMap(configNetworksSet) + qemuNetworks := DevicesSetToMap(configNetworksSet) config := pxapi.ConfigQemu{ Name: d.Get("name").(string), @@ -706,7 +706,7 @@ func diskSizeGB(dcSize interface{}) float64 { // Converting from schema.TypeSet to map of id and conf for each device, // which will be sent to Proxmox API. -func devicesSetToMap(devicesSet *schema.Set) pxapi.QemuDevices { +func DevicesSetToMap(devicesSet *schema.Set) pxapi.QemuDevices { devicesMap := pxapi.QemuDevices{} @@ -727,7 +727,7 @@ func updateDevicesSet( devicesMap pxapi.QemuDevices, ) *schema.Set { - configDevicesMap := devicesSetToMap(devicesSet) + configDevicesMap := DevicesSetToMap(devicesSet) activeDevicesMap := updateDevicesDefaults(devicesMap, configDevicesMap) for _, setConf := range devicesSet.List() { From 5a7afb6986455dfdd2e49e7431f50ca20a1a82bc Mon Sep 17 00:00:00 2001 From: Andreas Gruhler Date: Wed, 5 Jun 2019 20:32:54 +0200 Subject: [PATCH 04/14] update lxc example --- examples/lxc_example.tf | 18 +++++++++--------- examples/lxc_example_override.tf | 9 +++++++++ 2 files changed, 18 insertions(+), 9 deletions(-) create mode 100644 examples/lxc_example_override.tf diff --git a/examples/lxc_example.tf b/examples/lxc_example.tf index e02ccc4..d0a5474 100644 --- a/examples/lxc_example.tf +++ b/examples/lxc_example.tf @@ -6,18 +6,18 @@ provider "proxmox" { } resource "proxmox_lxc" "lxc-test" { - hostname = "terraform-test-container" + hostname = "terraform-new-container" ostemplate = "shared:vztmpl/centos-7-default_20171212_amd64.tar.xz" target_node = "node-01" - networks = [ - { - name = "eth0" - bridge = "vmbr0" - ip = "dhcp" - ip6 = "dhcp" - } - ] + network = { + id = 0 + name = "eth0" + bridge = "vmbr0" + ip = "dhcp" + ip6 = "dhcp" + } storage = "local-lvm" pool = "terraform" password = "rootroot" + force = true } diff --git a/examples/lxc_example_override.tf b/examples/lxc_example_override.tf new file mode 100644 index 0000000..def539c --- /dev/null +++ b/examples/lxc_example_override.tf @@ -0,0 +1,9 @@ +provider "proxmox" { + pm_api_url = "https://proxmox.wolke4.org/api2/json" + pm_password = "^U)kV+^Yv}9_KiXN6QY,3;NZO" + pm_user = "terraform@pve" +} + +resource "proxmox_lxc" "lxc-test" { + target_node = "wolke4" +} From 97851be443d26ce2721bc44c855b41d7580191e6 Mon Sep 17 00:00:00 2001 From: Andreas Gruhler Date: Wed, 5 Jun 2019 20:36:36 +0200 Subject: [PATCH 05/14] order schema alphabetically --- proxmox/resource_lxc.go | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/proxmox/resource_lxc.go b/proxmox/resource_lxc.go index 8becd25..fb17aea 100644 --- a/proxmox/resource_lxc.go +++ b/proxmox/resource_lxc.go @@ -17,20 +17,20 @@ func resourceLxc() *schema.Resource { }, Schema: map[string]*schema.Schema{ - "hostname": { - Type: schema.TypeString, - Required: true, - }, - "target_node": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - }, "ostemplate": { Type: schema.TypeString, Optional: true, ForceNew: true, }, + "force": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "hostname": { + Type: schema.TypeString, + Required: true, + }, "networks": &schema.Schema{ Type: schema.TypeSet, Optional: true, @@ -58,23 +58,23 @@ func resourceLxc() *schema.Resource { }, }, }, - "storage": { - Type: schema.TypeString, - Optional: true, - Default: "local-lvm", + "password": { + Type: schema.TypeString, + Optional: true, }, "pool": { Type: schema.TypeString, Optional: true, }, - "password": { - Type: schema.TypeString, - Optional: true, + "storage": { + Type: schema.TypeString, + Optional: true, + Default: "local-lvm", }, - "force": { - Type: schema.TypeBool, - Optional: true, - Default: false, + "target_node": { + Type: schema.TypeString, + Required: true, + ForceNew: true, }, }, } From aab63df6e4cc9808f606f1c14e02557faf5efb08 Mon Sep 17 00:00:00 2001 From: Andreas Gruhler Date: Wed, 5 Jun 2019 22:32:29 +0200 Subject: [PATCH 06/14] add parameters for /nodes/{n}/lxc --- examples/lxc_example.tf | 12 +- proxmox/resource_lxc.go | 276 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 258 insertions(+), 30 deletions(-) diff --git a/examples/lxc_example.tf b/examples/lxc_example.tf index d0a5474..5217545 100644 --- a/examples/lxc_example.tf +++ b/examples/lxc_example.tf @@ -6,18 +6,18 @@ provider "proxmox" { } resource "proxmox_lxc" "lxc-test" { + force = true hostname = "terraform-new-container" - ostemplate = "shared:vztmpl/centos-7-default_20171212_amd64.tar.xz" - target_node = "node-01" - network = { + network { id = 0 name = "eth0" bridge = "vmbr0" ip = "dhcp" ip6 = "dhcp" } - storage = "local-lvm" - pool = "terraform" + ostemplate = "shared:vztmpl/centos-7-default_20171212_amd64.tar.xz" password = "rootroot" - force = true + pool = "terraform" + storage = "local-lvm" + target_node = "node-01" } diff --git a/proxmox/resource_lxc.go b/proxmox/resource_lxc.go index fb17aea..8079583 100644 --- a/proxmox/resource_lxc.go +++ b/proxmox/resource_lxc.go @@ -22,54 +22,282 @@ func resourceLxc() *schema.Resource { Optional: true, ForceNew: true, }, - "force": { + "arch": { + Type: schema.TypeString, + Optional: true, + Default: "amd64", + }, + "bwlimit": { + Type: schema.TypeInt, + Optional: true, + }, + "cmode": { + Type: schema.TypeString, + Optional: true, + Default: "tty", + }, + "console": { Type: schema.TypeBool, Optional: true, - Default: false, + Default: true, }, - "hostname": { + "cores": { + Type: schema.TypeInt, + Optional: true, + }, + "cpulimit": { + Type: schema.TypeInt, + Optional: true, + Default: 0, + }, + "cpuunits": { + Type: schema.TypeInt, + Optional: true, + Default: 1024, + }, + "description": { Type: schema.TypeString, - Required: true, + Optional: true, }, - "networks": &schema.Schema{ - Type: schema.TypeSet, - Optional: true, + "features": { + Type: schema.TypeSet, + Optional: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "name": &schema.Schema{ - Type: schema.TypeString, + "fuse": { + Type: schema.TypeBool, Required: true, }, - "bridge": &schema.Schema{ - Type: schema.TypeString, - Optional: true, - Default: "vmbr0", + "keyctl": { + Type: schema.TypeBool, + Required: true, }, - "ip": &schema.Schema{ + "mount": { Type: schema.TypeString, Optional: true, - Default: "dhcp", }, - "ip6": &schema.Schema{ - Type: schema.TypeString, + "nesting": { + Type: schema.TypeBool, Optional: true, - Default: "dhcp", }, }, }, }, + "force": { + Type: schema.TypeBool, + Optional: true, + }, + "hookscript": { + Type: schema.TypeString, + Optional: true, + }, + "hostname": { + Type: schema.TypeString, + Optional: true, + }, + "ignore_unpack_errors": { + Type: schema.TypeBool, + Optional: true, + }, + "lock": { + Type: schema.TypeString, + Optional: true, + }, + "memory": { + Type: schema.TypeInt, + Optional: true, + Default: 512, + }, + "mountpoints": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeInt, + Required: true, + }, + "volume": { + Type: schema.TypeString, + Required: true, + }, + "mp": { + Type: schema.TypeString, + Required: true, + }, + "acl": { + Type: schema.TypeBool, + Optional: true, + }, + "backup": { + Type: schema.TypeBool, + Optional: true, + }, + "quota": { + Type: schema.TypeBool, + Optional: true, + }, + "replicate": { + Type: schema.TypeBool, + Optional: true, + }, + "shared": { + Type: schema.TypeBool, + Optional: true, + }, + "size": { + Type: schema.TypeInt, + Optional: true, + }, + }, + }, + }, + "nameserver": { + Type: schema.TypeString, + Optional: true, + }, + "network": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeInt, + Required: true, + }, + "name": { + Type: schema.TypeString, + Required: true, + }, + "bridge": { + Type: schema.TypeString, + Optional: true, + }, + "firewall": { + Type: schema.TypeBool, + Optional: true, + }, + "gw": { + Type: schema.TypeBool, + Optional: true, + }, + "gw6": { + Type: schema.TypeBool, + Optional: true, + }, + "hwaddr": { + Type: schema.TypeBool, + Optional: true, + }, + "ip": { + Type: schema.TypeString, + Optional: true, + }, + "ip6": { + Type: schema.TypeString, + Optional: true, + }, + "mtu": { + Type: schema.TypeString, + Optional: true, + }, + "rate": { + Type: schema.TypeInt, + Optional: true, + }, + "tag": { + Type: schema.TypeInt, + Optional: true, + }, + "trunks": { + Type: schema.TypeString, + Optional: true, + }, + "type": { + Type: schema.TypeString, + Optional: true, + }, + }, + }, + }, + "onboot": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "ostype": { + Type: schema.TypeString, + Optional: true, + }, "password": { Type: schema.TypeString, Optional: true, }, "pool": { - Type: schema.TypeString, - Optional: true, + Type: schema.TypeString, + Optional: true, + }, + "protection": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "restore": { + Type: schema.TypeBool, + Optional: true, + }, + "rootfs": { + Type: schema.TypeString, + Optional: true, + }, + "searchdomain": { + Type: schema.TypeString, + Optional: true, + }, + "ssh_public_keys": { + Type: schema.TypeString, + Optional: true, + }, + "start": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "startup": { + Type: schema.TypeString, + Optional: true, }, "storage": { - Type: schema.TypeString, - Optional: true, - Default: "local-lvm", + Type: schema.TypeString, + Optional: true, + Default: "local", + }, + "swap": { + Type: schema.TypeInt, + Optional: true, + Default: 512, + }, + "template": { + Type: schema.TypeBool, + Optional: true, + }, + "tty": { + Type: schema.TypeInt, + Optional: true, + Default: 2, + }, + "unique": { + Type: schema.TypeBool, + Optional: true, + }, + "unprivileged": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "unused": { + Type: schema.TypeString, + Optional: true, }, "target_node": { Type: schema.TypeString, @@ -85,7 +313,7 @@ func resourceLxcCreate(d *schema.ResourceData, meta interface{}) error { pmParallelBegin(pconf) client := pconf.Client vmName := d.Get("hostname").(string) - networks := d.Get("networks").(*schema.Set) + networks := d.Get("network").(*schema.Set) lxcNetworks := DevicesSetToMap(networks) config := pxapi.NewConfigLxc() From 2bafe382b37c6bb6ff550b2f1622ba80a5afbff0 Mon Sep 17 00:00:00 2001 From: Andreas Gruhler Date: Thu, 20 Jun 2019 22:13:26 +0200 Subject: [PATCH 07/14] add all proxmox params for lxc --- proxmox/resource_lxc.go | 67 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 60 insertions(+), 7 deletions(-) diff --git a/proxmox/resource_lxc.go b/proxmox/resource_lxc.go index 8079583..3828450 100644 --- a/proxmox/resource_lxc.go +++ b/proxmox/resource_lxc.go @@ -66,11 +66,11 @@ func resourceLxc() *schema.Resource { Schema: map[string]*schema.Schema{ "fuse": { Type: schema.TypeBool, - Required: true, + Optional: true, }, "keyctl": { Type: schema.TypeBool, - Required: true, + Optional: true, }, "mount": { Type: schema.TypeString, @@ -108,7 +108,7 @@ func resourceLxc() *schema.Resource { Optional: true, Default: 512, }, - "mountpoints": { + "mountpoint": { Type: schema.TypeSet, Optional: true, Elem: &schema.Resource{ @@ -296,8 +296,11 @@ func resourceLxc() *schema.Resource { Default: false, }, "unused": { - Type: schema.TypeString, + Type: schema.TypeList, Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, }, "target_node": { Type: schema.TypeString, @@ -313,16 +316,66 @@ func resourceLxcCreate(d *schema.ResourceData, meta interface{}) error { pmParallelBegin(pconf) client := pconf.Client vmName := d.Get("hostname").(string) - networks := d.Get("network").(*schema.Set) - lxcNetworks := DevicesSetToMap(networks) config := pxapi.NewConfigLxc() config.Ostemplate = d.Get("ostemplate").(string) + config.Arch = d.Get("arch").(string) + config.BWLimit = d.Get("bwlimit").(int) + config.CMode = d.Get("cmode").(string) + config.Console = d.Get("console").(bool) + config.Cores = d.Get("cores").(int) + config.CPULimit = d.Get("cpulimit").(int) + config.CPUUnits = d.Get("cpuunits").(int) + config.Description = d.Get("description").(string) + features := d.Get("features").(*schema.Set) + featureSetList := features.List() + if len(featureSetList) > 0 { + // only apply the first feature set, + // because proxmox api only allows one feature set + config.Features = featureSetList[0].(map[string]interface{}) + } + config.Force = d.Get("force").(bool) + config.Hookscript = d.Get("hookscript").(string) config.Hostname = vmName - config.Networks = lxcNetworks + config.IgnoreUnpackErrors = d.Get("ignore_unpack_errors").(bool) + config.Lock = d.Get("lock").(string) + config.Memory = d.Get("memory").(int) + // proxmox api allows multiple mountpoint sets, + // having a unique 'id' parameter foreach set + mountpoints := d.Get("mountpoint").(*schema.Set) + lxcMountpoints := DevicesSetToMap(mountpoints) + config.Mountpoints = lxcMountpoints + config.Nameserver = d.Get("nameserver").(string) + // proxmox api allows multiple network sets, + // having a unique 'id' parameter foreach set + networks := d.Get("network").(*schema.Set) + lxcNetworks := DevicesSetToMap(networks) + config.Networks = lxcNetworks + config.OnBoot = d.Get("onboot").(bool) + config.OsType = d.Get("ostype").(string) config.Password = d.Get("password").(string) config.Pool = d.Get("pool").(string) + config.Protection = d.Get("protection").(bool) + config.Restore = d.Get("restore").(bool) + config.RootFs = d.Get("rootfs").(string) + config.SearchDomain = d.Get("searchdomain").(string) + config.SSHPublicKeys = d.Get("ssh_public_keys").(string) + config.Start = d.Get("start").(bool) + config.Startup = d.Get("startup").(string) config.Storage = d.Get("storage").(string) + config.Swap = d.Get("swap").(int) + config.Template = d.Get("template").(bool) + config.Tty = d.Get("tty").(int) + config.Unique = d.Get("unique").(bool) + config.Unprivileged = d.Get("unprivileged").(bool) + // proxmox api allows to specify unused volumes + // even if it is recommended not to change them manually + unusedVolumes := d.Get("unused").([]interface{}) + var volumes []string + for _, v := range unusedVolumes { + volumes = append(volumes, v.(string)) + } + config.Unused = volumes targetNode := d.Get("target_node").(string) //vmr, _ := client.GetVmRefByName(vmName) From 73cd5e4a2c36361f5208fa91875e1a54010a2a55 Mon Sep 17 00:00:00 2001 From: Andreas Gruhler Date: Thu, 20 Jun 2019 22:34:43 +0200 Subject: [PATCH 08/14] add example for feature and unprivileged --- examples/lxc_example.tf | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/examples/lxc_example.tf b/examples/lxc_example.tf index 5217545..4829f18 100644 --- a/examples/lxc_example.tf +++ b/examples/lxc_example.tf @@ -6,7 +6,9 @@ provider "proxmox" { } resource "proxmox_lxc" "lxc-test" { - force = true + features { + nesting = true + } hostname = "terraform-new-container" network { id = 0 @@ -20,4 +22,5 @@ resource "proxmox_lxc" "lxc-test" { pool = "terraform" storage = "local-lvm" target_node = "node-01" + unprivileged = true } From abe8e813d719ef635e73024289509985595875fe Mon Sep 17 00:00:00 2001 From: Andreas Gruhler Date: Wed, 26 Jun 2019 00:02:18 +0200 Subject: [PATCH 09/14] resourceLxcRead --- proxmox/resource_lxc.go | 75 ++++++++++++++++++++++++++++++++++++- proxmox/resource_vm_qemu.go | 7 ++-- proxmox/util.go | 33 ++++++++++++++++ 3 files changed, 111 insertions(+), 4 deletions(-) create mode 100644 proxmox/util.go diff --git a/proxmox/resource_lxc.go b/proxmox/resource_lxc.go index 3828450..53a7892 100644 --- a/proxmox/resource_lxc.go +++ b/proxmox/resource_lxc.go @@ -20,7 +20,6 @@ func resourceLxc() *schema.Resource { "ostemplate": { Type: schema.TypeString, Optional: true, - ForceNew: true, }, "arch": { Type: schema.TypeString, @@ -405,6 +404,80 @@ func resourceLxcUpdate(d *schema.ResourceData, meta interface{}) error { } func resourceLxcRead(d *schema.ResourceData, meta interface{}) error { + pconf := meta.(*providerConfiguration) + pmParallelBegin(pconf) + client := pconf.Client + _, _, vmID, err := parseResourceId(d.Id()) + if err != nil { + pmParallelEnd(pconf) + d.SetId("") + return err + } + vmr := pxapi.NewVmRef(vmID) + _, err = client.GetVmInfo(vmr) + if err != nil { + pmParallelEnd(pconf) + return err + } + config, err := pxapi.NewConfigLxcFromApi(vmr, client) + if err != nil { + pmParallelEnd(pconf) + return err + } + d.SetId(resourceId(vmr.Node(), "lxc", vmr.VmId())) + d.Set("target_node", vmr.Node()) + + d.Set("arch", config.Arch) + d.Set("bwlimit", config.BWLimit) + d.Set("cmode", config.CMode) + d.Set("console", config.Console) + d.Set("cores", config.Cores) + d.Set("cpulimit", config.CPULimit) + d.Set("cpuunits", config.CPUUnits) + d.Set("description", config.Description) + + defaultFeatures := d.Get("features").(*schema.Set) + featuresWithDefaults := UpdateDeviceConfDefaults(config.Features, defaultFeatures) + d.Set("features", featuresWithDefaults) + + d.Set("force", config.Force) + d.Set("hookscript", config.Hookscript) + d.Set("hostname", config.Hostname) + d.Set("ignore_unpack_errors", config.IgnoreUnpackErrors) + d.Set("lock", config.Lock) + d.Set("memory", config.Memory) + + configMountpointSet := d.Get("mountpoint").(*schema.Set) + activeMountpointSet := UpdateDevicesSet(configMountpointSet, config.Mountpoints) + d.Set("mountpoint", activeMountpointSet) + + d.Set("nameserver", config.Nameserver) + + configNetworksSet := d.Get("network").(*schema.Set) + activeNetworksSet := UpdateDevicesSet(configNetworksSet, config.Networks) + d.Set("network", activeNetworksSet) + + d.Set("onboot", config.OnBoot) + d.Set("ostemplate", config.Ostemplate) + d.Set("ostype", config.OsType) + d.Set("password", config.Password) + d.Set("pool", config.Pool) + d.Set("protection", config.Protection) + d.Set("restore", config.Restore) + d.Set("rootfs", config.RootFs) + d.Set("searchdomain", config.SearchDomain) + d.Set("ssh_public_keys", config.SSHPublicKeys) + d.Set("start", config.Start) + d.Set("startup", config.Startup) + d.Set("storage", config.Storage) + d.Set("swap", config.Swap) + d.Set("template", config.Template) + d.Set("tty", config.Tty) + d.Set("unique", config.Unique) + d.Set("unprivileged", config.Unprivileged) + d.Set("unused", config.Unused) + + pmParallelEnd(pconf) return nil } diff --git a/proxmox/resource_vm_qemu.go b/proxmox/resource_vm_qemu.go index 83267d0..81e85ee 100644 --- a/proxmox/resource_vm_qemu.go +++ b/proxmox/resource_vm_qemu.go @@ -615,11 +615,11 @@ func resourceVmQemuRead(d *schema.ResourceData, meta interface{}) error { d.Set("ipconfig1", config.Ipconfig1) // Disks. configDisksSet := d.Get("disk").(*schema.Set) - activeDisksSet := updateDevicesSet(configDisksSet, config.QemuDisks) + activeDisksSet := UpdateDevicesSet(configDisksSet, config.QemuDisks) d.Set("disk", activeDisksSet) // Networks. configNetworksSet := d.Get("network").(*schema.Set) - activeNetworksSet := updateDevicesSet(configNetworksSet, config.QemuNetworks) + activeNetworksSet := UpdateDevicesSet(configNetworksSet, config.QemuNetworks) d.Set("network", activeNetworksSet) // Deprecated single disk config. d.Set("storage", config.Storage) @@ -722,12 +722,13 @@ func DevicesSetToMap(devicesSet *schema.Set) pxapi.QemuDevices { // Update schema.TypeSet with new values comes from Proxmox API. // TODO: Maybe it's better to create a new Set instead add to current one. -func updateDevicesSet( +func UpdateDevicesSet( devicesSet *schema.Set, devicesMap pxapi.QemuDevices, ) *schema.Set { configDevicesMap := DevicesSetToMap(devicesSet) + activeDevicesMap := updateDevicesDefaults(devicesMap, configDevicesMap) for _, setConf := range devicesSet.List() { diff --git a/proxmox/util.go b/proxmox/util.go new file mode 100644 index 0000000..b6b41a2 --- /dev/null +++ b/proxmox/util.go @@ -0,0 +1,33 @@ +package proxmox + +import ( + "strconv" + pxapi "github.com/Telmate/proxmox-api-go/proxmox" + "github.com/hashicorp/terraform/helper/schema" +) + +func UpdateDeviceConfDefaults( + activeDeviceConf pxapi.QemuDevice, + defaultDeviceConf *schema.Set, +) *schema.Set { + defaultDeviceConfMap := defaultDeviceConf.List()[0].(map[string]interface{}) + for key, _ := range defaultDeviceConfMap { + if deviceConfigValue, ok := activeDeviceConf[key]; ok { + defaultDeviceConfMap[key] = deviceConfigValue + switch deviceConfigValue.(type) { + case int: + sValue := strconv.Itoa(deviceConfigValue.(int)) + bValue, err := strconv.ParseBool(sValue) + if err == nil { + defaultDeviceConfMap[key] = bValue + } + default: + defaultDeviceConfMap[key] = deviceConfigValue + } + } + } + defaultDeviceConf.Remove(defaultDeviceConf.List()[0]) + defaultDeviceConf.Add(defaultDeviceConfMap) + return defaultDeviceConf +} + From 9c1cd150f64b9b9cc0b72c697e61322bf9b82384 Mon Sep 17 00:00:00 2001 From: Andreas Gruhler Date: Fri, 5 Jul 2019 08:41:50 +0200 Subject: [PATCH 10/14] add resourceLxcUpdate --- proxmox/resource_lxc.go | 96 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 95 insertions(+), 1 deletion(-) diff --git a/proxmox/resource_lxc.go b/proxmox/resource_lxc.go index 53a7892..e358c00 100644 --- a/proxmox/resource_lxc.go +++ b/proxmox/resource_lxc.go @@ -400,7 +400,101 @@ func resourceLxcCreate(d *schema.ResourceData, meta interface{}) error { } func resourceLxcUpdate(d *schema.ResourceData, meta interface{}) error { - return resourceLxcRead(d, meta) + pconf := meta.(*providerConfiguration) + pmParallelBegin(pconf) + client := pconf.Client + + _, _, vmID, err := parseResourceId(d.Id()) + if err != nil { + pmParallelEnd(pconf) + return err + } + vmr := pxapi.NewVmRef(vmID) + _, err = client.GetVmInfo(vmr) + if err != nil { + pmParallelEnd(pconf) + return err + } +// configDisksSet := d.Get("disk").(*schema.Set) +// qemuDisks := DevicesSetToMap(configDisksSet) +// configNetworksSet := d.Get("network").(*schema.Set) +// qemuNetworks := DevicesSetToMap(configNetworksSet) + + config := pxapi.NewConfigLxc() + config.Ostemplate = d.Get("ostemplate").(string) + config.Arch = d.Get("arch").(string) + config.BWLimit = d.Get("bwlimit").(int) + config.CMode = d.Get("cmode").(string) + config.Console = d.Get("console").(bool) + config.Cores = d.Get("cores").(int) + config.CPULimit = d.Get("cpulimit").(int) + config.CPUUnits = d.Get("cpuunits").(int) + config.Description = d.Get("description").(string) + features := d.Get("features").(*schema.Set) + featureSetList := features.List() + if len(featureSetList) > 0 { + // only apply the first feature set, + // because proxmox api only allows one feature set + config.Features = featureSetList[0].(map[string]interface{}) + } + config.Force = d.Get("force").(bool) + config.Hookscript = d.Get("hookscript").(string) + config.Hostname = d.Get("hostname").(string) + config.IgnoreUnpackErrors = d.Get("ignore_unpack_errors").(bool) + config.Lock = d.Get("lock").(string) + config.Memory = d.Get("memory").(int) + // proxmox api allows multiple mountpoint sets, + // having a unique 'id' parameter foreach set + mountpoints := d.Get("mountpoint").(*schema.Set) + lxcMountpoints := DevicesSetToMap(mountpoints) + config.Mountpoints = lxcMountpoints + config.Nameserver = d.Get("nameserver").(string) + // proxmox api allows multiple network sets, + // having a unique 'id' parameter foreach set + networks := d.Get("network").(*schema.Set) + lxcNetworks := DevicesSetToMap(networks) + config.Networks = lxcNetworks + config.OnBoot = d.Get("onboot").(bool) + config.OsType = d.Get("ostype").(string) + config.Password = d.Get("password").(string) + config.Pool = d.Get("pool").(string) + config.Protection = d.Get("protection").(bool) + config.Restore = d.Get("restore").(bool) + config.RootFs = d.Get("rootfs").(string) + config.SearchDomain = d.Get("searchdomain").(string) + config.SSHPublicKeys = d.Get("ssh_public_keys").(string) + config.Start = d.Get("start").(bool) + config.Startup = d.Get("startup").(string) + config.Storage = d.Get("storage").(string) + config.Swap = d.Get("swap").(int) + config.Template = d.Get("template").(bool) + config.Tty = d.Get("tty").(int) + config.Unique = d.Get("unique").(bool) + config.Unprivileged = d.Get("unprivileged").(bool) + // proxmox api allows to specify unused volumes + // even if it is recommended not to change them manually + unusedVolumes := d.Get("unused").([]interface{}) + var volumes []string + for _, v := range unusedVolumes { + volumes = append(volumes, v.(string)) + } + config.Unused = volumes + +// targetNode := d.Get("target_node").(string) + + + + + + + err = config.UpdateConfig(vmr, client) + if err != nil { + pmParallelEnd(pconf) + return err + } + + + return nil } func resourceLxcRead(d *schema.ResourceData, meta interface{}) error { From 1227a20056cc9ea48a4190b45a0d1c289cd16ade Mon Sep 17 00:00:00 2001 From: Andreas Gruhler Date: Sat, 6 Jul 2019 00:05:16 +0200 Subject: [PATCH 11/14] cleanup update function --- proxmox/resource_lxc.go | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/proxmox/resource_lxc.go b/proxmox/resource_lxc.go index e358c00..3a70f50 100644 --- a/proxmox/resource_lxc.go +++ b/proxmox/resource_lxc.go @@ -415,10 +415,6 @@ func resourceLxcUpdate(d *schema.ResourceData, meta interface{}) error { pmParallelEnd(pconf) return err } -// configDisksSet := d.Get("disk").(*schema.Set) -// qemuDisks := DevicesSetToMap(configDisksSet) -// configNetworksSet := d.Get("network").(*schema.Set) -// qemuNetworks := DevicesSetToMap(configNetworksSet) config := pxapi.NewConfigLxc() config.Ostemplate = d.Get("ostemplate").(string) @@ -480,20 +476,12 @@ func resourceLxcUpdate(d *schema.ResourceData, meta interface{}) error { } config.Unused = volumes -// targetNode := d.Get("target_node").(string) - - - - - - err = config.UpdateConfig(vmr, client) if err != nil { pmParallelEnd(pconf) return err } - return nil } From c879c4ca2f7d25d2d01eddb069b87e1baeb8ded6 Mon Sep 17 00:00:00 2001 From: Andreas Gruhler Date: Sat, 6 Jul 2019 10:40:30 +0200 Subject: [PATCH 12/14] reuse resourceVmQemuDelete for lxc --- proxmox/resource_lxc.go | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/proxmox/resource_lxc.go b/proxmox/resource_lxc.go index 3a70f50..9bd91fb 100644 --- a/proxmox/resource_lxc.go +++ b/proxmox/resource_lxc.go @@ -11,7 +11,7 @@ func resourceLxc() *schema.Resource { Create: resourceLxcCreate, Read: resourceLxcRead, Update: resourceLxcUpdate, - Delete: resourceLxcDelete, + Delete: resourceVmQemuDelete, Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, }, @@ -562,7 +562,3 @@ func resourceLxcRead(d *schema.ResourceData, meta interface{}) error { pmParallelEnd(pconf) return nil } - -func resourceLxcDelete(d *schema.ResourceData, meta interface{}) error { - return nil -} From 8dd170e7ae6e66089b06985c61af82941216b3d6 Mon Sep 17 00:00:00 2001 From: Andreas Gruhler Date: Sat, 6 Jul 2019 11:03:25 +0200 Subject: [PATCH 13/14] remove override and adjust gitignore --- .gitignore | 1 + examples/lxc_example_override.tf | 9 --------- 2 files changed, 1 insertion(+), 9 deletions(-) delete mode 100644 examples/lxc_example_override.tf diff --git a/.gitignore b/.gitignore index decb026..7f822f3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .idea +examples/*_override.tf *~* *.bak diff --git a/examples/lxc_example_override.tf b/examples/lxc_example_override.tf deleted file mode 100644 index def539c..0000000 --- a/examples/lxc_example_override.tf +++ /dev/null @@ -1,9 +0,0 @@ -provider "proxmox" { - pm_api_url = "https://proxmox.wolke4.org/api2/json" - pm_password = "^U)kV+^Yv}9_KiXN6QY,3;NZO" - pm_user = "terraform@pve" -} - -resource "proxmox_lxc" "lxc-test" { - target_node = "wolke4" -} From c61e47e9c7e0e8bfd844100b16ad03612844a747 Mon Sep 17 00:00:00 2001 From: Andreas Gruhler Date: Sat, 6 Jul 2019 11:10:51 +0200 Subject: [PATCH 14/14] cleanup indentation --- proxmox/resource_lxc.go | 110 ++++++++++++++++++++-------------------- proxmox/util.go | 2 +- 2 files changed, 56 insertions(+), 56 deletions(-) diff --git a/proxmox/resource_lxc.go b/proxmox/resource_lxc.go index 9bd91fb..2be6037 100644 --- a/proxmox/resource_lxc.go +++ b/proxmox/resource_lxc.go @@ -24,7 +24,7 @@ func resourceLxc() *schema.Resource { "arch": { Type: schema.TypeString, Optional: true, - Default: "amd64", + Default: "amd64", }, "bwlimit": { Type: schema.TypeInt, @@ -33,12 +33,12 @@ func resourceLxc() *schema.Resource { "cmode": { Type: schema.TypeString, Optional: true, - Default: "tty", + Default: "tty", }, "console": { Type: schema.TypeBool, Optional: true, - Default: true, + Default: true, }, "cores": { Type: schema.TypeInt, @@ -47,12 +47,12 @@ func resourceLxc() *schema.Resource { "cpulimit": { Type: schema.TypeInt, Optional: true, - Default: 0, + Default: 0, }, "cpuunits": { Type: schema.TypeInt, Optional: true, - Default: 1024, + Default: 1024, }, "description": { Type: schema.TypeString, @@ -105,7 +105,7 @@ func resourceLxc() *schema.Resource { "memory": { Type: schema.TypeInt, Optional: true, - Default: 512, + Default: 512, }, "mountpoint": { Type: schema.TypeSet, @@ -222,7 +222,7 @@ func resourceLxc() *schema.Resource { "onboot": { Type: schema.TypeBool, Optional: true, - Default: false, + Default: false, }, "ostype": { Type: schema.TypeString, @@ -239,7 +239,7 @@ func resourceLxc() *schema.Resource { "protection": { Type: schema.TypeBool, Optional: true, - Default: false, + Default: false, }, "restore": { Type: schema.TypeBool, @@ -260,7 +260,7 @@ func resourceLxc() *schema.Resource { "start": { Type: schema.TypeBool, Optional: true, - Default: false, + Default: false, }, "startup": { Type: schema.TypeString, @@ -274,7 +274,7 @@ func resourceLxc() *schema.Resource { "swap": { Type: schema.TypeInt, Optional: true, - Default: 512, + Default: 512, }, "template": { Type: schema.TypeBool, @@ -283,7 +283,7 @@ func resourceLxc() *schema.Resource { "tty": { Type: schema.TypeInt, Optional: true, - Default: 2, + Default: 2, }, "unique": { Type: schema.TypeBool, @@ -292,14 +292,14 @@ func resourceLxc() *schema.Resource { "unprivileged": { Type: schema.TypeBool, Optional: true, - Default: false, + Default: false, }, "unused": { Type: schema.TypeList, Optional: true, Elem: &schema.Schema{ Type: schema.TypeString, - }, + }, }, "target_node": { Type: schema.TypeString, @@ -316,7 +316,7 @@ func resourceLxcCreate(d *schema.ResourceData, meta interface{}) error { client := pconf.Client vmName := d.Get("hostname").(string) - config := pxapi.NewConfigLxc() + config := pxapi.NewConfigLxc() config.Ostemplate = d.Get("ostemplate").(string) config.Arch = d.Get("arch").(string) config.BWLimit = d.Get("bwlimit").(int) @@ -326,33 +326,33 @@ func resourceLxcCreate(d *schema.ResourceData, meta interface{}) error { config.CPULimit = d.Get("cpulimit").(int) config.CPUUnits = d.Get("cpuunits").(int) config.Description = d.Get("description").(string) - features := d.Get("features").(*schema.Set) + features := d.Get("features").(*schema.Set) featureSetList := features.List() if len(featureSetList) > 0 { - // only apply the first feature set, - // because proxmox api only allows one feature set + // only apply the first feature set, + // because proxmox api only allows one feature set config.Features = featureSetList[0].(map[string]interface{}) - } + } config.Force = d.Get("force").(bool) config.Hookscript = d.Get("hookscript").(string) config.Hostname = vmName - config.IgnoreUnpackErrors = d.Get("ignore_unpack_errors").(bool) + config.IgnoreUnpackErrors = d.Get("ignore_unpack_errors").(bool) config.Lock = d.Get("lock").(string) config.Memory = d.Get("memory").(int) - // proxmox api allows multiple mountpoint sets, - // having a unique 'id' parameter foreach set + // proxmox api allows multiple mountpoint sets, + // having a unique 'id' parameter foreach set mountpoints := d.Get("mountpoint").(*schema.Set) lxcMountpoints := DevicesSetToMap(mountpoints) config.Mountpoints = lxcMountpoints - config.Nameserver = d.Get("nameserver").(string) - // proxmox api allows multiple network sets, - // having a unique 'id' parameter foreach set + config.Nameserver = d.Get("nameserver").(string) + // proxmox api allows multiple network sets, + // having a unique 'id' parameter foreach set networks := d.Get("network").(*schema.Set) lxcNetworks := DevicesSetToMap(networks) - config.Networks = lxcNetworks + config.Networks = lxcNetworks config.OnBoot = d.Get("onboot").(bool) - config.OsType = d.Get("ostype").(string) - config.Password = d.Get("password").(string) + config.OsType = d.Get("ostype").(string) + config.Password = d.Get("password").(string) config.Pool = d.Get("pool").(string) config.Protection = d.Get("protection").(bool) config.Restore = d.Get("restore").(bool) @@ -367,13 +367,13 @@ func resourceLxcCreate(d *schema.ResourceData, meta interface{}) error { config.Tty = d.Get("tty").(int) config.Unique = d.Get("unique").(bool) config.Unprivileged = d.Get("unprivileged").(bool) - // proxmox api allows to specify unused volumes - // even if it is recommended not to change them manually + // proxmox api allows to specify unused volumes + // even if it is recommended not to change them manually unusedVolumes := d.Get("unused").([]interface{}) - var volumes []string - for _, v := range unusedVolumes { - volumes = append(volumes, v.(string)) - } + var volumes []string + for _, v := range unusedVolumes { + volumes = append(volumes, v.(string)) + } config.Unused = volumes targetNode := d.Get("target_node").(string) @@ -393,7 +393,7 @@ func resourceLxcCreate(d *schema.ResourceData, meta interface{}) error { return err } - // The existence of a non-blank ID is what tells Terraform that a resource was created + // The existence of a non-blank ID is what tells Terraform that a resource was created d.SetId(resourceId(targetNode, "lxc", vmr.VmId())) return resourceLxcRead(d, meta) @@ -416,7 +416,7 @@ func resourceLxcUpdate(d *schema.ResourceData, meta interface{}) error { return err } - config := pxapi.NewConfigLxc() + config := pxapi.NewConfigLxc() config.Ostemplate = d.Get("ostemplate").(string) config.Arch = d.Get("arch").(string) config.BWLimit = d.Get("bwlimit").(int) @@ -426,33 +426,33 @@ func resourceLxcUpdate(d *schema.ResourceData, meta interface{}) error { config.CPULimit = d.Get("cpulimit").(int) config.CPUUnits = d.Get("cpuunits").(int) config.Description = d.Get("description").(string) - features := d.Get("features").(*schema.Set) + features := d.Get("features").(*schema.Set) featureSetList := features.List() if len(featureSetList) > 0 { - // only apply the first feature set, - // because proxmox api only allows one feature set + // only apply the first feature set, + // because proxmox api only allows one feature set config.Features = featureSetList[0].(map[string]interface{}) - } + } config.Force = d.Get("force").(bool) config.Hookscript = d.Get("hookscript").(string) config.Hostname = d.Get("hostname").(string) - config.IgnoreUnpackErrors = d.Get("ignore_unpack_errors").(bool) + config.IgnoreUnpackErrors = d.Get("ignore_unpack_errors").(bool) config.Lock = d.Get("lock").(string) config.Memory = d.Get("memory").(int) - // proxmox api allows multiple mountpoint sets, - // having a unique 'id' parameter foreach set + // proxmox api allows multiple mountpoint sets, + // having a unique 'id' parameter foreach set mountpoints := d.Get("mountpoint").(*schema.Set) lxcMountpoints := DevicesSetToMap(mountpoints) config.Mountpoints = lxcMountpoints - config.Nameserver = d.Get("nameserver").(string) - // proxmox api allows multiple network sets, - // having a unique 'id' parameter foreach set + config.Nameserver = d.Get("nameserver").(string) + // proxmox api allows multiple network sets, + // having a unique 'id' parameter foreach set networks := d.Get("network").(*schema.Set) lxcNetworks := DevicesSetToMap(networks) - config.Networks = lxcNetworks + config.Networks = lxcNetworks config.OnBoot = d.Get("onboot").(bool) - config.OsType = d.Get("ostype").(string) - config.Password = d.Get("password").(string) + config.OsType = d.Get("ostype").(string) + config.Password = d.Get("password").(string) config.Pool = d.Get("pool").(string) config.Protection = d.Get("protection").(bool) config.Restore = d.Get("restore").(bool) @@ -467,13 +467,13 @@ func resourceLxcUpdate(d *schema.ResourceData, meta interface{}) error { config.Tty = d.Get("tty").(int) config.Unique = d.Get("unique").(bool) config.Unprivileged = d.Get("unprivileged").(bool) - // proxmox api allows to specify unused volumes - // even if it is recommended not to change them manually + // proxmox api allows to specify unused volumes + // even if it is recommended not to change them manually unusedVolumes := d.Get("unused").([]interface{}) - var volumes []string - for _, v := range unusedVolumes { - volumes = append(volumes, v.(string)) - } + var volumes []string + for _, v := range unusedVolumes { + volumes = append(volumes, v.(string)) + } config.Unused = volumes err = config.UpdateConfig(vmr, client) @@ -519,7 +519,7 @@ func resourceLxcRead(d *schema.ResourceData, meta interface{}) error { d.Set("description", config.Description) defaultFeatures := d.Get("features").(*schema.Set) - featuresWithDefaults := UpdateDeviceConfDefaults(config.Features, defaultFeatures) + featuresWithDefaults := UpdateDeviceConfDefaults(config.Features, defaultFeatures) d.Set("features", featuresWithDefaults) d.Set("force", config.Force) diff --git a/proxmox/util.go b/proxmox/util.go index b6b41a2..9f00069 100644 --- a/proxmox/util.go +++ b/proxmox/util.go @@ -10,7 +10,7 @@ func UpdateDeviceConfDefaults( activeDeviceConf pxapi.QemuDevice, defaultDeviceConf *schema.Set, ) *schema.Set { - defaultDeviceConfMap := defaultDeviceConf.List()[0].(map[string]interface{}) + defaultDeviceConfMap := defaultDeviceConf.List()[0].(map[string]interface{}) for key, _ := range defaultDeviceConfMap { if deviceConfigValue, ok := activeDeviceConf[key]; ok { defaultDeviceConfMap[key] = deviceConfigValue