Skip to content
This repository has been archived by the owner on Aug 14, 2020. It is now read-only.

Commit

Permalink
Add Catalog and media item attribute metadata (vmware#298)
Browse files Browse the repository at this point in the history
* Add metada support for catalog and media items
* bump govcd version
* Increase version

Signed-off-by: Vaidotas Bauzys <vbauzys@vmware.com>
  • Loading branch information
vbauzys committed Aug 2, 2019
1 parent c85dc93 commit 0f7e4be
Show file tree
Hide file tree
Showing 25 changed files with 746 additions and 57 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
@@ -1,4 +1,8 @@
## 2.5.0 (Unreleased)

* `resource/catalog_item` added catalog item metadata support [#28*]
* `resource/catalog_media` added catalog media item metadata support [#28*]

## 2.4.0 (July 29, 2019)

FEATURES:
Expand Down
2 changes: 1 addition & 1 deletion VERSION
@@ -1 +1 @@
v2.4.0
v2.5.0
2 changes: 1 addition & 1 deletion go.mod
Expand Up @@ -4,5 +4,5 @@ go 1.12

require (
github.com/hashicorp/terraform v0.12.0
github.com/vmware/go-vcloud-director/v2 v2.3.1
github.com/vmware/go-vcloud-director/v2 v2.4.0-alpha.1
)
4 changes: 2 additions & 2 deletions go.sum
Expand Up @@ -301,8 +301,8 @@ github.com/ulikunitz/xz v0.5.5/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4A
github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
github.com/vmihailenco/msgpack v4.0.1+incompatible h1:RMF1enSPeKTlXrXdOcqjFUElywVZjjC6pqse21bKbEU=
github.com/vmihailenco/msgpack v4.0.1+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
github.com/vmware/go-vcloud-director/v2 v2.3.1 h1:O2VUliXvZyaS0T6/5ciNUM0eG2aaKPXu+1Kn83rcqHA=
github.com/vmware/go-vcloud-director/v2 v2.3.1/go.mod h1:+Hq7ryFfgZqsO6mXH29RQFnpIMSujCOMI57otHoXHhQ=
github.com/vmware/go-vcloud-director/v2 v2.4.0-alpha.1 h1:pWbgSIRyNjeTvb4S7RGHtvxxWDLXtkkQLQ7IMwxbZXU=
github.com/vmware/go-vcloud-director/v2 v2.4.0-alpha.1/go.mod h1:+Hq7ryFfgZqsO6mXH29RQFnpIMSujCOMI57otHoXHhQ=
github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
github.com/xiang90/probing v0.0.0-20160813154853-07dd2e8dfe18/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xlab/treeprint v0.0.0-20161029104018-1d6e34225557/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg=
Expand Down
10 changes: 5 additions & 5 deletions vcd/catalogitem.go
Expand Up @@ -43,30 +43,30 @@ func deleteCatalogItem(d *schema.ResourceData, vcdClient *VCDClient) error {
}

// Finds catalog item which can be vapp template OVA or media ISO file
func findCatalogItem(d *schema.ResourceData, vcdClient *VCDClient) error {
func findCatalogItem(d *schema.ResourceData, vcdClient *VCDClient) (*govcd.CatalogItem, error) {
log.Printf("[TRACE] Catalog item read initiated")

adminOrg, err := vcdClient.GetAdminOrgFromResource(d)
if err != nil {
return fmt.Errorf(errorRetrievingOrg, err)
return nil, fmt.Errorf(errorRetrievingOrg, err)
}

catalog, err := adminOrg.FindCatalog(d.Get("catalog").(string))
if err != nil || catalog == (govcd.Catalog{}) {
log.Printf("[DEBUG] Unable to find catalog. Removing from tfstate")
d.SetId("")
return nil
return nil, nil
}

catalogItem, err := catalog.FindCatalogItem(d.Get("name").(string))
if err != nil || catalogItem == (govcd.CatalogItem{}) {
log.Printf("[DEBUG] Unable to find catalog item. Removing from tfstate")
d.SetId("")
return nil
return nil, nil
}

log.Printf("[TRACE] Catalog item read completed: %#v", catalogItem.CatalogItem)
return nil
return &catalogItem, nil
}

func getError(task govcd.UploadTask) error {
Expand Down
1 change: 1 addition & 0 deletions vcd/config_test.go
Expand Up @@ -244,6 +244,7 @@ func templateFill(tmpl string, data StringMap) string {
data["Url"] = testConfig.Provider.Url
data["SysOrg"] = testConfig.Provider.SysOrg
data["Org"] = testConfig.VCD.Org
data["Vdc"] = testConfig.VCD.Vdc
data["AllowInsecure"] = testConfig.Provider.AllowInsecure
data["MaxRetryTimeout"] = testConfig.Provider.MaxRetryTimeout
data["VersionRequired"] = currentProviderVersion
Expand Down
94 changes: 91 additions & 3 deletions vcd/resource_vcd_catalog_item.go
Expand Up @@ -60,6 +60,13 @@ func resourceVcdCatalogItem() *schema.Resource {
ForceNew: false,
Description: "shows upload progress in stdout",
},
"metadata": {
Type: schema.TypeMap,
Optional: true,
Description: "Key and value pairs for catalog item metadata",
// For now underlying go-vcloud-director repo only supports
// a value of type String in this map.
},
},
}
}
Expand Down Expand Up @@ -133,18 +140,99 @@ func resourceVcdCatalogItemCreate(d *schema.ResourceData, meta interface{}) erro
d.SetId(catalogName + ":" + itemName)

log.Printf("[TRACE] Catalog item created: %#v", itemName)

err = createOrUpdateCatalogItemMetadata(d, meta)
if err != nil {
return fmt.Errorf("error adding catalog item metadata: %s", err)
}

return resourceVcdCatalogItemRead(d, meta)
}

func resourceVcdCatalogItemRead(d *schema.ResourceData, meta interface{}) error {
return findCatalogItem(d, meta.(*VCDClient))
catalogItem, err := findCatalogItem(d, meta.(*VCDClient))
if err != nil {
return err
}

vAppTemplate, err := catalogItem.GetVAppTemplate()
if err != nil {
return err
}

metadata, err := vAppTemplate.GetMetadata()
d.Set("metadata", getMetadataStruct(metadata.MetadataEntry))
return err
}

func resourceVcdCatalogItemDelete(d *schema.ResourceData, meta interface{}) error {
return deleteCatalogItem(d, meta.(*VCDClient))
}

//update function for "show_upload_progress" and "upload_piece_size"
func resourceVcdCatalogItemUpdate(d *schema.ResourceData, m interface{}) error {
// currently updates only metadata
func resourceVcdCatalogItemUpdate(d *schema.ResourceData, meta interface{}) error {
err := createOrUpdateCatalogItemMetadata(d, meta)
if err != nil {
return fmt.Errorf("error updating catalog item metadata: %s", err)
}
return nil
}

func createOrUpdateCatalogItemMetadata(d *schema.ResourceData, meta interface{}) error {

log.Printf("[TRACE] adding/updating metadata for catalog item")

vcdClient := meta.(*VCDClient)

adminOrg, err := vcdClient.GetAdminOrgFromResource(d)
if err != nil {
return fmt.Errorf(errorRetrievingOrg, err)
}

catalog, err := adminOrg.FindCatalog(d.Get("catalog").(string))
if err != nil || catalog == (govcd.Catalog{}) {
log.Printf("[DEBUG] Unable to find catalog: %s", err)
return nil
}

catalogItem, err := catalog.FindCatalogItem(d.Get("name").(string))
if err != nil || catalogItem == (govcd.CatalogItem{}) {
log.Printf("[DEBUG] Unable to find catalog item: %s", err)
return nil
}

// We have to add metadata to template to see in UI
// catalog item is another abstraction and has own metadata which we don't see in UI
vAppTemplate, err := catalogItem.GetVAppTemplate()
if err != nil {
return err
}

if d.HasChange("metadata") {
oldRaw, newRaw := d.GetChange("metadata")
oldMetadata := oldRaw.(map[string]interface{})
newMetadata := newRaw.(map[string]interface{})
var toBeRemovedMetadata []string
// Check if any key in old metadata was removed in new metadata.
// Creates a list of keys to be removed.
for k := range oldMetadata {
if _, ok := newMetadata[k]; !ok {
toBeRemovedMetadata = append(toBeRemovedMetadata, k)
}
}
for _, k := range toBeRemovedMetadata {
err := vAppTemplate.DeleteMetadata(k)
if err != nil {
return fmt.Errorf("error deleting metadata: %s", err)
}
}
// Add new metadata
for k, v := range newMetadata {
_, err := vAppTemplate.AddMetadata(k, v.(string))
if err != nil {
return fmt.Errorf("error adding metadata: %s", err)
}
}
}
return nil
}
46 changes: 46 additions & 0 deletions vcd/resource_vcd_catalog_item_test.go
Expand Up @@ -30,6 +30,8 @@ func TestAccVcdCatalogItemBasic(t *testing.T) {
}

configText := templateFill(testAccCheckVcdCatalogItemBasic, params)
params["FuncName"] = t.Name() + "-Update"
updateConfigText := templateFill(testAccCheckVcdCatalogItemUpdate, params)
if vcdShortTest {
t.Skip(acceptanceTestsSkipped)
return
Expand All @@ -49,6 +51,26 @@ func TestAccVcdCatalogItemBasic(t *testing.T) {
"vcd_catalog_item."+TestAccVcdCatalogItem, "name", TestAccVcdCatalogItem),
resource.TestCheckResourceAttr(
"vcd_catalog_item."+TestAccVcdCatalogItem, "description", TestAccVcdCatalogItemDescription),
resource.TestCheckResourceAttr(
"vcd_catalog_item."+TestAccVcdCatalogItem, "metadata.catalogItem_metadata", "catalogItem Metadata"),
resource.TestCheckResourceAttr(
"vcd_catalog_item."+TestAccVcdCatalogItem, "metadata.catalogItem_metadata2", "catalogItem Metadata2"),
),
},
resource.TestStep{
Config: updateConfigText,
Check: resource.ComposeTestCheckFunc(
testAccCheckVcdCatalogItemExists("vcd_catalog_item."+TestAccVcdCatalogItem, &catalogItem),
resource.TestCheckResourceAttr(
"vcd_catalog_item."+TestAccVcdCatalogItem, "name", TestAccVcdCatalogItem),
resource.TestCheckResourceAttr(
"vcd_catalog_item."+TestAccVcdCatalogItem, "description", TestAccVcdCatalogItemDescription),
resource.TestCheckResourceAttr(
"vcd_catalog_item."+TestAccVcdCatalogItem, "metadata.catalogItem_metadata", "catalogItem Metadata v2"),
resource.TestCheckResourceAttr(
"vcd_catalog_item."+TestAccVcdCatalogItem, "metadata.catalogItem_metadata2", "catalogItem Metadata2 v2"),
resource.TestCheckResourceAttr(
"vcd_catalog_item."+TestAccVcdCatalogItem, "metadata.catalogItem_metadata3", "catalogItem Metadata3"),
),
},
},
Expand Down Expand Up @@ -148,5 +170,29 @@ const testAccCheckVcdCatalogItemBasic = `
ova_path = "{{.OvaPath}}"
upload_piece_size = {{.UploadPieceSize}}
show_upload_progress = "{{.UploadProgress}}"
metadata = {
catalogItem_metadata = "catalogItem Metadata"
catalogItem_metadata2 = "catalogItem Metadata2"
}
}
`

const testAccCheckVcdCatalogItemUpdate = `
resource "vcd_catalog_item" "{{.CatalogItemName}}" {
org = "{{.Org}}"
catalog = "{{.Catalog}}"
name = "{{.CatalogItemName}}"
description = "{{.Description}}"
ova_path = "{{.OvaPath}}"
upload_piece_size = {{.UploadPieceSize}}
show_upload_progress = "{{.UploadProgress}}"
metadata = {
catalogItem_metadata = "catalogItem Metadata v2"
catalogItem_metadata2 = "catalogItem Metadata2 v2"
catalogItem_metadata3 = "catalogItem Metadata3"
}
}
`
89 changes: 86 additions & 3 deletions vcd/resource_vcd_catalog_media.go
Expand Up @@ -60,6 +60,13 @@ func resourceVcdCatalogMedia() *schema.Resource {
ForceNew: false,
Description: "shows upload progress in stdout",
},
"metadata": {
Type: schema.TypeMap,
Optional: true,
Description: "Key and value pairs for catalog item metadata",
// For now underlying go-vcloud-director repo only supports
// a value of type String in this map.
},
},
}
}
Expand Down Expand Up @@ -128,6 +135,12 @@ func resourceVcdMediaCreate(d *schema.ResourceData, meta interface{}) error {
d.SetId(catalogName + ":" + mediaName)

log.Printf("[TRACE] Catalog media created: %#v", mediaName)

err = createOrUpdateMediaItemMetadata(d, meta)
if err != nil {
return fmt.Errorf("error adding media item metadata: %s", err)
}

return resourceVcdMediaRead(d, meta)
}

Expand All @@ -142,14 +155,84 @@ func GetTerraformStdout() *os.File {
}

func resourceVcdMediaRead(d *schema.ResourceData, meta interface{}) error {
return findCatalogItem(d, meta.(*VCDClient))
vcdClient := meta.(*VCDClient)

_, vdc, err := vcdClient.GetOrgAndVdc("", "")
if err != nil {
return fmt.Errorf(errorRetrievingOrg, err)
}

mediaItem, err := vdc.FindMediaImage(d.Get("name").(string))
if err != nil || mediaItem == (govcd.MediaItem{}) {
log.Printf("[DEBUG] Unable to find media item: %s", err)
return err
}

metadata, err := mediaItem.GetMetadata()
if err != nil {
log.Printf("[DEBUG] Unable to find media item metadata: %s", err)
return err
}

d.Set("metadata", getMetadataStruct(metadata.MetadataEntry))
return err
}

func resourceVcdMediaDelete(d *schema.ResourceData, meta interface{}) error {
return deleteCatalogItem(d, meta.(*VCDClient))
}

//update function for "show_upload_progress" and "upload_piece_size"
func resourceVcdMediaUpdate(d *schema.ResourceData, m interface{}) error {
// currently updates only metadata
func resourceVcdMediaUpdate(d *schema.ResourceData, meta interface{}) error {
err := createOrUpdateMediaItemMetadata(d, meta)
if err != nil {
return fmt.Errorf("error updating media item metadata: %s", err)
}
return resourceVcdMediaRead(d, meta)
}

func createOrUpdateMediaItemMetadata(d *schema.ResourceData, meta interface{}) error {

log.Printf("[TRACE] adding/updating metadata for media item")

vcdClient := meta.(*VCDClient)

_, vdc, err := vcdClient.GetOrgAndVdc("", "")
if err != nil {
return fmt.Errorf(errorRetrievingOrg, err)
}

mediaItem, err := vdc.FindMediaImage(d.Get("name").(string))
if err != nil || mediaItem == (govcd.MediaItem{}) {
log.Printf("[DEBUG] Unable to find media item: %s", err)
return fmt.Errorf("unable to find media item: %s", err)
}

if d.HasChange("metadata") {
oldRaw, newRaw := d.GetChange("metadata")
oldMetadata := oldRaw.(map[string]interface{})
newMetadata := newRaw.(map[string]interface{})
var toBeRemovedMetadata []string
// Check if any key in old metadata was removed in new metadata.
// Creates a list of keys to be removed.
for k := range oldMetadata {
if _, ok := newMetadata[k]; !ok {
toBeRemovedMetadata = append(toBeRemovedMetadata, k)
}
}
for _, k := range toBeRemovedMetadata {
err := mediaItem.DeleteMetadata(k)
if err != nil {
return fmt.Errorf("error deleting metadata: %s", err)
}
}
// Add new metadata
for k, v := range newMetadata {
_, err = mediaItem.AddMetadata(k, v.(string))
if err != nil {
return fmt.Errorf("error adding metadata: %s", err)
}
}
}
return nil
}

0 comments on commit 0f7e4be

Please sign in to comment.