Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add handling of vApp name and description #664

Merged
merged 7 commits into from
Apr 30, 2021
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .changes/v3.3.0/664-bug-fixes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
* (Issue #633) vApp description was ignored in creation and update. [GH-664]

6 changes: 5 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ require (
github.com/aws/aws-sdk-go v1.30.12 // indirect
github.com/hashicorp/go-version v1.2.1
github.com/hashicorp/terraform-plugin-sdk/v2 v2.4.4
github.com/kr/pretty v0.2.0
github.com/kr/pretty v0.2.1
github.com/vmware/go-vcloud-director/v2 v2.12.0-alpha.1
)

replace github.com/vmware/go-vcloud-director/v2 => github.com/dataclouder/go-vcloud-director/v2 v2.5.0-alpha.4.0.20210429082455-9994e0748a7b

// replace github.com/vmware/go-vcloud-director/v2 => ../go-vcloud-director
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/dataclouder/go-vcloud-director/v2 v2.5.0-alpha.4.0.20210429082455-9994e0748a7b h1:iwwXGfMu8siHWjUmputOf47Caq3OV2YnqVhv2yEIWjU=
github.com/dataclouder/go-vcloud-director/v2 v2.5.0-alpha.4.0.20210429082455-9994e0748a7b/go.mod h1:poaOwg7CoXO4m9Pv4TVhMpNF1wQQwKzxpdGYTfjzajs=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand Down Expand Up @@ -218,8 +220,8 @@ github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT
github.com/keybase/go-crypto v0.0.0-20161004153544-93f5b35093ba/go.mod h1:ghbZscTyKdM07+Fw3KSi0hcJm+AlEUWj8QLlPtijN/M=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs=
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
Expand Down Expand Up @@ -288,8 +290,6 @@ github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oW
github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI=
github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
github.com/vmware/go-vcloud-director/v2 v2.12.0-alpha.1 h1:0/C6CI0YsrM+uMt0Lf1/CI5pA1Ff9d1ZMmuqjdEpC9I=
github.com/vmware/go-vcloud-director/v2 v2.12.0-alpha.1/go.mod h1:czvTQZlB4/WsOsL7rMVCb+SYAPJhx/dYoS/Sk7rc/O0=
github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70=
github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
Expand Down
9 changes: 8 additions & 1 deletion vcd/resource_vcd_vapp.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,11 @@ func resourceVcdVAppCreate(d *schema.ResourceData, meta interface{}) error {
}

vappName := d.Get("name").(string)
vappDescription := d.Get("description").(string)
vcdClient.lockVapp(d)
defer vcdClient.unLockVapp(d)

e := vdc.ComposeRawVApp(d.Get("name").(string))
e := vdc.ComposeRawVApp(vappName, vappDescription)

if e != nil {
return fmt.Errorf("error: %#v", e)
Expand Down Expand Up @@ -151,6 +152,12 @@ func resourceVcdVAppUpdate(d *schema.ResourceData, meta interface{}) error {
return fmt.Errorf("error finding VApp: %#v", err)
}

if d.HasChange("name") || d.HasChange("description") {
Didainius marked this conversation as resolved.
Show resolved Hide resolved
err = vapp.UpdateNameDescription(d.Get("name").(string), d.Get("description").(string))
if err != nil {
return fmt.Errorf("error updating VApp: %s", err)
}
}
if d.HasChange("guest_properties") {
vappProperties, err := getGuestProperties(d)
if err != nil {
Expand Down
30 changes: 19 additions & 11 deletions vcd/resource_vcd_vapp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,27 @@ func TestAccVcdVApp_Basic(t *testing.T) {
preTestChecks(t)
var vapp govcd.VApp
var vappName = "TestAccVcdVAppVapp"
var vappDescription = "A long description containing some text."
var vappUpdateDescription = "A shorter description."

var params = StringMap{
"Org": testConfig.VCD.Org,
"Vdc": testConfig.VCD.Vdc,
"EdgeGateway": testConfig.Networking.EdgeGateway,
"NetworkName": "TestAccVcdVAppNet",
"NetworkName2": "TestAccVcdVAppNet2",
"NetworkName3": "TestAccVcdVAppNet3",
"Catalog": testSuiteCatalogName,
"CatalogItem": testSuiteCatalogOVAItem,
"VappName": vappName,
"FuncName": "TestAccCheckVcdVApp_PowerOff",
"Tags": "vapp",
"Org": testConfig.VCD.Org,
"Vdc": testConfig.VCD.Vdc,
"EdgeGateway": testConfig.Networking.EdgeGateway,
"NetworkName": "TestAccVcdVAppNet",
"NetworkName2": "TestAccVcdVAppNet2",
"NetworkName3": "TestAccVcdVAppNet3",
"Catalog": testSuiteCatalogName,
"CatalogItem": testSuiteCatalogOVAItem,
"VappName": vappName,
"VappDescription": vappDescription,
"FuncName": "TestAccVcdVApp_Basic",
"Tags": "vapp",
}
configText := templateFill(testAccCheckVcdVApp_basic, params)

params["FuncName"] = "TestAccCheckVcdVApp_update"
params["VappDescription"] = vappUpdateDescription
configTextUpdate := templateFill(testAccCheckVcdVApp_update, params)
if vcdShortTest {
t.Skip(acceptanceTestsSkipped)
Expand All @@ -51,6 +55,7 @@ func TestAccVcdVApp_Basic(t *testing.T) {
Check: resource.ComposeTestCheckFunc(
testAccCheckVcdVAppExists("vcd_vapp."+vappName, &vapp),
resource.TestCheckResourceAttr("vcd_vapp."+vappName, "name", vappName),
resource.TestCheckResourceAttr("vcd_vapp."+vappName, "description", vappDescription),
resource.TestCheckResourceAttr("vcd_vapp."+vappName, "status", "1"),
resource.TestCheckResourceAttr("vcd_vapp."+vappName, "metadata.vapp_metadata", "vApp Metadata."),
resource.TestMatchResourceAttr("vcd_vapp."+vappName, "href",
Expand All @@ -65,6 +70,7 @@ func TestAccVcdVApp_Basic(t *testing.T) {
Check: resource.ComposeTestCheckFunc(
testAccCheckVcdVAppExists("vcd_vapp."+vappName, &vapp),
resource.TestCheckResourceAttr("vcd_vapp."+vappName, "name", vappName),
resource.TestCheckResourceAttr("vcd_vapp."+vappName, "description", vappUpdateDescription),
resource.TestCheckResourceAttr("vcd_vapp."+vappName, "power_on", "true"),
resource.TestCheckResourceAttr("vcd_vapp."+vappName, "status", "4"),
resource.TestCheckResourceAttr("vcd_vapp."+vappName, "metadata.vapp_metadata", "vApp Metadata updated"),
Expand Down Expand Up @@ -149,6 +155,7 @@ resource "vcd_vapp" "{{.VappName}}" {
org = "{{.Org}}"
vdc = "{{.Vdc}}"
name = "{{.VappName}}"
description = "{{.VappDescription}}"

metadata = {
vapp_metadata = "vApp Metadata."
Expand Down Expand Up @@ -180,6 +187,7 @@ resource "vcd_vapp" "{{.VappName}}" {
org = "{{.Org}}"
vdc = "{{.Vdc}}"
name = "{{.VappName}}"
description = "{{.VappDescription}}"

metadata = {
vapp_metadata = "vApp Metadata updated"
Expand Down
112 changes: 112 additions & 0 deletions vcd/resource_vcd_vapp_update_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// +build vapp ALL functional

package vcd

import (
"strings"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/vmware/go-vcloud-director/v2/govcd"
)

func TestAccVcdVAppUpdate(t *testing.T) {
preTestChecks(t)
var vapp govcd.VApp
var vappName = t.Name()
var vappDescription = "A long description going up to 256 characters. " + strings.Repeat("x", 209)
var vappUpdateDescription = "A shorter description."
var vappUpdateName = vappName + "_new"

var params = StringMap{
"Org": testConfig.VCD.Org,
"Vdc": testConfig.VCD.Vdc,
"VappDef": vappName,
"VappName": vappName,
"VappDescription": vappDescription,
"FuncName": t.Name(),
"Note": "",
"Tags": "vapp",
}
configText := templateFill(testAccVcdVAppUpdate, params)

params["FuncName"] = t.Name() + "_update"
params["VappDescription"] = vappUpdateDescription
params["VappName"] = vappUpdateName
params["Note"] = "# skip-binary-test: only for updates"
configTextUpdate := templateFill(testAccVcdVAppUpdate, params)

params["FuncName"] = t.Name() + "_removal"
params["VappDescription"] = ""
configRemoveDescription := templateFill(testAccVcdVAppUpdate, params)

params["FuncName"] = t.Name() + "_restore"
params["VappDescription"] = vappDescription
params["VappName"] = vappName
configTextRestore := templateFill(testAccVcdVAppUpdate, params)

if vcdShortTest {
t.Skip(acceptanceTestsSkipped)
return
}
debugPrintf("#[DEBUG] CONFIGURATION basic: %s\n", configText)
debugPrintf("#[DEBUG] CONFIGURATION update: %s\n", configTextUpdate)
debugPrintf("#[DEBUG] CONFIGURATION removal: %s\n", configRemoveDescription)
debugPrintf("#[DEBUG] CONFIGURATION restore: %s\n", configTextRestore)

resourceName := "vcd_vapp." + vappName
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProviderFactories: testAccProviders,
CheckDestroy: testAccCheckVcdVAppDestroy,
Steps: []resource.TestStep{
// Deploy vApp
resource.TestStep{
Config: configText,
Check: resource.ComposeTestCheckFunc(
testAccCheckVcdVAppExists(resourceName, &vapp),
resource.TestCheckResourceAttr(resourceName, "name", vappName),
resource.TestCheckResourceAttr(resourceName, "description", vappDescription),
),
},
// Rename vApp and update description
resource.TestStep{
Config: configTextUpdate,
Check: resource.ComposeTestCheckFunc(
testAccCheckVcdVAppExists(resourceName, &vapp),
resource.TestCheckResourceAttr(resourceName, "name", vappUpdateName),
resource.TestCheckResourceAttr(resourceName, "description", vappUpdateDescription),
),
},
// remove description
resource.TestStep{
Config: configRemoveDescription,
Check: resource.ComposeTestCheckFunc(
testAccCheckVcdVAppExists(resourceName, &vapp),
resource.TestCheckResourceAttr(resourceName, "name", vappUpdateName),
resource.TestCheckResourceAttr(resourceName, "description", ""),
),
},
// Restore original values
resource.TestStep{
Config: configTextRestore,
Check: resource.ComposeTestCheckFunc(
testAccCheckVcdVAppExists(resourceName, &vapp),
resource.TestCheckResourceAttr(resourceName, "name", vappName),
resource.TestCheckResourceAttr(resourceName, "description", vappDescription),
),
},
},
})
postTestChecks(t)
}

const testAccVcdVAppUpdate = `
{{.Note}}
resource "vcd_vapp" "{{.VappDef}}" {
org = "{{.Org}}"
vdc = "{{.Vdc}}"
name = "{{.VappName}}"
description = "{{.VappDescription}}"
}
`
6 changes: 3 additions & 3 deletions vcd/resource_vcd_vm_affinity_rule_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -387,9 +387,9 @@ func testAccCheckVmAffinityRuleDestroy(rule *govcd.VmAffinityRule, orgName, vdcN
}

// makeEmptyVapp creates a given vApp without any VM
func makeEmptyVapp(vdc *govcd.Vdc, name string) (*govcd.VApp, error) {
func makeEmptyVapp(vdc *govcd.Vdc, name string, description string) (*govcd.VApp, error) {

err := vdc.ComposeRawVApp(name)
err := vdc.ComposeRawVApp(name, description)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -487,7 +487,7 @@ func makeVappGroup(label string, vdc *govcd.Vdc, groupDefinition map[string][]st
if vcdTestVerbose {
fmt.Printf("Creating vApp %s\n", vappName)
}
vapp, err := makeEmptyVapp(vdc, vappName)
vapp, err := makeEmptyVapp(vdc, vappName, "")
if err != nil {
return nil, err
}
Expand Down
1 change: 1 addition & 0 deletions website/docs/d/vapp.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ The following arguments are supported:

## Attribute reference

* `description` An optional description for the vApp
* `href` - The vApp Hyper Reference
* `metadata` - Key value map of metadata to assign to this vApp. Key and value can be any string.
* `guest_properties` - Key value map of vApp guest properties.
Expand Down
1 change: 1 addition & 0 deletions website/docs/r/vapp.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ The following arguments are supported:
* `name` - (Required) A unique name for the vApp
* `org` - (Optional; *v2.0+*) The name of organization to use, optional if defined at provider level. Useful when connected as sysadmin working across different organisations
* `vdc` - (Optional; *v2.0+*) The name of VDC to use, optional if defined at provider level
* `description` (Optional; *v3.3*) An optional description for the vApp, up to 256 characters.
* `power_on` - (Optional) A boolean value stating if this vApp should be powered on. Default is `false`. Works only on update when vApp already has VMs.
* `metadata` - (Optional) Key value map of metadata to assign to this vApp. Key and value can be any string. (Since *v2.2+* metadata is added directly to vApp instead of first VM in vApp)
* `guest_properties` - (Optional; *v2.5+*) Key value map of vApp guest properties
Expand Down