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 generic CRUD metadata by href functions #454

Merged
merged 11 commits into from
Apr 6, 2022
5 changes: 5 additions & 0 deletions .changes/v2.15.0/454-features.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
* Added support to set, get and delete metadata to the following resources via its HREF:
`catalog`, `catalog item`, `edge gateway`, `independent disk`, `media`, `network`, `org`, `PVDC`, `PVDC storage profile`, `vApp`, `vApp template`,`VDC` and `VDC storage profile`;
with the methods
`VCDClient.GetMetadataByHref`, `VCDClient.AddMetadataEntryByHref`, `VCDClient.AddMetadataEntryByHrefAsync`,
`VCDClient.DeleteMetadataEntryByHref` and `VCDClient.DeleteMetadataEntryByHrefAsync` [GH-454]
38 changes: 38 additions & 0 deletions govcd/metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,44 @@ import (
"github.com/vmware/go-vcloud-director/v2/types/v56"
)

// GetMetadataByHref returns metadata from the given resource reference.
func (vcdClient *VCDClient) GetMetadataByHref(href string) (*types.Metadata, error) {
return getMetadata(&vcdClient.Client, href)
}

// AddMetadataEntryByHref adds metadata typedValue and key/value pair provided as input to the given resource reference,
// then waits for the task to finish.
func (vcdClient *VCDClient) AddMetadataEntryByHref(href, typedValue, key, value string) error {
task, err := vcdClient.AddMetadataEntryByHrefAsync(href, typedValue, key, value)
if err != nil {
return err
}
return task.WaitTaskCompletion()
}

// AddMetadataEntryByHrefAsync adds metadata typedValue and key/value pair provided as input to the given resource reference
// and returns the task.
func (vcdClient *VCDClient) AddMetadataEntryByHrefAsync(href, typedValue, key, value string) (Task, error) {
return addMetadata(&vcdClient.Client, typedValue, key, value, href)
}

// DeleteMetadataEntryByHref deletes metadata from the given resource reference, depending on key provided as input
// and waits for the task to finish.
func (vcdClient *VCDClient) DeleteMetadataEntryByHref(href, key string) error {
task, err := vcdClient.DeleteMetadataEntryByHrefAsync(href, key)
if err != nil {
return err
}

return task.WaitTaskCompletion()
}

// DeleteMetadataEntryByHrefAsync deletes metadata from the given resource reference, depending on key provided as input
// and returns a task.
func (vcdClient *VCDClient) DeleteMetadataEntryByHrefAsync(href, key string) (Task, error) {
return deleteMetadata(&vcdClient.Client, key, href)
}

// GetMetadata returns VM metadata.
func (vm *VM) GetMetadata() (*types.Metadata, error) {
return getMetadata(vm.client, vm.VM.HREF)
Expand Down
60 changes: 60 additions & 0 deletions govcd/metadata_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ package govcd

import (
"fmt"
"strings"

"github.com/vmware/go-vcloud-director/v2/types/v56"

Expand Down Expand Up @@ -940,3 +941,62 @@ func (vcd *TestVCD) Test_MetadataOnOpenApiOrgVdcNetworkCRUD(check *C) {
check.Assert(metadata, NotNil)
check.Assert(len(metadata.MetadataEntry), Equals, 0)
}

func (vcd *TestVCD) Test_MetadataByHrefCRUD(check *C) {
fmt.Printf("Running: %s\n", check.TestName())
storageProfileRef, err := vcd.vdc.FindStorageProfileReference(vcd.config.VCD.StorageProfile.SP1)
if err != nil {
check.Skip(fmt.Sprintf("Test_MetadataByHrefCRUD: Storage Profile %s not found. Test can't proceed", vcd.config.VCD.StorageProfile.SP1))
return
}

storageProfileAdminHref := strings.ReplaceAll(storageProfileRef.HREF, "api", "api/admin")

// Check how much metadata exists
metadata, err := vcd.client.GetMetadataByHref(storageProfileAdminHref)
check.Assert(err, IsNil)
check.Assert(metadata, NotNil)
existingMetaDataCount := len(metadata.MetadataEntry)

// Add metadata
err = vcd.client.AddMetadataEntryByHref(storageProfileAdminHref, types.MetadataStringValue, "key", "value")
check.Assert(err, IsNil)

// Check if metadata was added correctly
metadata, err = vcd.client.GetMetadataByHref(storageProfileAdminHref)
check.Assert(err, IsNil)
check.Assert(metadata, NotNil)
check.Assert(len(metadata.MetadataEntry), Equals, existingMetaDataCount+1)
var foundEntry *types.MetadataEntry
for _, entry := range metadata.MetadataEntry {
if entry.Key == "key" {
foundEntry = entry
}
}
check.Assert(foundEntry, NotNil)
check.Assert(foundEntry.Key, Equals, "key")
check.Assert(foundEntry.TypedValue.Value, Equals, "value")

// Check the same without admin privileges
metadata, err = vcd.client.GetMetadataByHref(storageProfileRef.HREF)
check.Assert(err, IsNil)
check.Assert(metadata, NotNil)
check.Assert(len(metadata.MetadataEntry), Equals, existingMetaDataCount+1)
for _, entry := range metadata.MetadataEntry {
if entry.Key == "key" {
foundEntry = entry
}
}
check.Assert(foundEntry, NotNil)
check.Assert(foundEntry.Key, Equals, "key")
check.Assert(foundEntry.TypedValue.Value, Equals, "value")

// Delete the metadata
err = vcd.client.DeleteMetadataEntryByHref(storageProfileAdminHref, "key")
check.Assert(err, IsNil)
// Check if metadata was deleted correctly
metadata, err = vcd.client.GetMetadataByHref(storageProfileAdminHref)
check.Assert(err, IsNil)
check.Assert(metadata, NotNil)
check.Assert(len(metadata.MetadataEntry), Equals, 0)
}