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

Update vdc storage profiles #393

Merged
merged 14 commits into from
Aug 6, 2021
4 changes: 4 additions & 0 deletions .changes/v2.13.0/393-deprecations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
* Deprecated `GetStorageProfileByHref` in favor of either `client.GetStorageProfileByHref` or `vcdClient.GetStorageProfileByHref` [GH-393]
* Deprecated `QueryProviderVdcStorageProfileByName` in favor of `VCDClient.QueryProviderVdcStorageProfileByName` [GH-393]
* Deprecated `VCDClient.QueryProviderVdcStorageProfiles` in favor of either `client.QueryProviderVdcStorageProfiles` or `client.QueryAllProviderVdcStorageProfiles` [GH-393]
* Deprecated `Vdc.GetDefaultStorageProfileReference` in favor of `adminVdc.GetDefaultStorageProfileReference` [GH-393]
11 changes: 11 additions & 0 deletions .changes/v2.13.0/393-features.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
* Added method `AdminVdc.AddStorageProfile` [GH-393]
* Added method `AdminVdc.AddStorageProfileWait` [GH-393]
* Added method `AdminVdc.RemoveStorageProfile` [GH-393]
* Added method `AdminVdc.RemoveStorageProfileWait` [GH-393]
* Added method `AdminVdc.SetDefaultStorageProfile` [GH-393]
* Added method `AdminVdc.GetDefaultStorageProfileReference` [GH-393]
* Added method `VCDClient.GetStorageProfileByHref` [GH-393]
* Added method `Client.GetStorageProfileByHref` [GH-393]
* Added method `VCDClient.QueryProviderVdcStorageProfileByName` [GH-393]
* Added method `Client.QueryAllProviderVdcStorageProfiles` [GH-393]
* Added method `Client.QueryProviderVdcStorageProfiles` [GH-393]
168 changes: 168 additions & 0 deletions govcd/adminvdc.go
Original file line number Diff line number Diff line change
Expand Up @@ -424,3 +424,171 @@ func (vdc *AdminVdc) UpdateStorageProfile(storageProfileId string, storageProfil

return updateAdminVdcStorageProfile, err
}

// AddStorageProfile adds a storage profile to a VDC
func (vdc *AdminVdc) AddStorageProfile(storageProfile *types.VdcStorageProfileConfiguration, description string) (Task, error) {
if vdc.client.VCDHREF.String() == "" {
return Task{}, fmt.Errorf("cannot add VDC storage profile, VCD HREF is unset")
}

href := vdc.AdminVdc.HREF + "/vdcStorageProfiles"

var updateStorageProfile = types.UpdateVdcStorageProfiles{
Xmlns: types.XMLNamespaceVCloud,
Name: storageProfile.ProviderVdcStorageProfile.Name,
Description: description,
AddStorageProfile: storageProfile,
RemoveStorageProfile: nil,
}

task, err := vdc.client.ExecuteTaskRequest(href, http.MethodPost,
types.MimeUpdateVdcStorageProfiles, "error adding VDC storage profile: %s", &updateStorageProfile)
if err != nil {
return Task{}, fmt.Errorf("cannot add VDC storage profile, error: %s", err)
}

return task, nil
}

// AddStorageProfileWait adds a storage profile to a VDC and return a refreshed VDC
func (vdc *AdminVdc) AddStorageProfileWait(storageProfile *types.VdcStorageProfileConfiguration, description string) error {
task, err := vdc.AddStorageProfile(storageProfile, description)
if err != nil {
return err
}
err = task.WaitTaskCompletion()
if err != nil {
return err
}
return vdc.Refresh()
}

// RemoveStorageProfile remove a storage profile from a VDC
func (vdc *AdminVdc) RemoveStorageProfile(storageProfileName string) (Task, error) {
if vdc.client.VCDHREF.String() == "" {
return Task{}, fmt.Errorf("cannot remove VDC storage profile: VCD HREF is unset")
}

var storageProfile *types.Reference
for _, sp := range vdc.AdminVdc.VdcStorageProfiles.VdcStorageProfile {
if sp.Name == storageProfileName {
storageProfile = sp
}
}
if storageProfile == nil {
return Task{}, fmt.Errorf("cannot remove VDC storage profile: storage profile '%s' not found in VDC", storageProfileName)
}

vdcStorageProfileDetails, err := vdc.client.GetStorageProfileByHref(storageProfile.HREF)
if err != nil {
return Task{}, fmt.Errorf("cannot retrieve VDC storage profile '%s' details: %s", storageProfileName, err)
}
if vdcStorageProfileDetails.Enabled {
_, err = vdc.UpdateStorageProfile(extractUuid(storageProfile.HREF), &types.AdminVdcStorageProfile{
Name: vdcStorageProfileDetails.Name,
Units: vdcStorageProfileDetails.Units,
Limit: vdcStorageProfileDetails.Limit,
Default: false,
Enabled: takeBoolPointer(false),
ProviderVdcStorageProfile: &types.Reference{
HREF: vdcStorageProfileDetails.ProviderVdcStorageProfile.HREF,
},
},
)
if err != nil {
return Task{}, fmt.Errorf("cannot disable VDC storage profile '%s': %s", storageProfileName, err)
}
}

href := vdc.AdminVdc.HREF + "/vdcStorageProfiles"

var updateStorageProfile = types.UpdateVdcStorageProfiles{
Xmlns: types.XMLNamespaceVCloud,
Name: vdcStorageProfileDetails.Name,
Description: "",
RemoveStorageProfile: storageProfile,
}

task, err := vdc.client.ExecuteTaskRequest(href, http.MethodPost,
types.MimeUpdateVdcStorageProfiles, "error removing VDC storage profile: %s", &updateStorageProfile)
if err != nil {
return Task{}, fmt.Errorf("cannot remove VDC storage profile, error: %s", err)
}

return task, nil
}

// RemoveStorageProfileWait removes a storege profile from a VDC and returns a refreshed VDC or an error
func (vdc *AdminVdc) RemoveStorageProfileWait(storageProfileName string) error {
task, err := vdc.RemoveStorageProfile(storageProfileName)
if err != nil {
return err
}
err = task.WaitTaskCompletion()
if err != nil {
return err
}
return vdc.Refresh()
}

// SetDefaultStorageProfile sets a given storage profile as default
// This operation will automatically unset the previous default storage profile.
func (vdc *AdminVdc) SetDefaultStorageProfile(storageProfileName string) error {
if vdc.client.VCDHREF.String() == "" {
return fmt.Errorf("cannot Set VDC default storage profile: VCD HREF is unset")
dataclouder marked this conversation as resolved.
Show resolved Hide resolved
}

var storageProfile *types.Reference
for _, sp := range vdc.AdminVdc.VdcStorageProfiles.VdcStorageProfile {
if sp.Name == storageProfileName {
storageProfile = sp
}
}
if storageProfile == nil {
return fmt.Errorf("cannot set VDC default storage profile: storage profile '%s' not found in VDC", storageProfileName)
}

vdcStorageProfileDetails, err := vdc.client.GetStorageProfileByHref(storageProfile.HREF)
if err != nil {
return fmt.Errorf("cannot retrieve VDC storage profile '%s' details: %s", storageProfileName, err)
}
_, err = vdc.UpdateStorageProfile(extractUuid(storageProfile.HREF), &types.AdminVdcStorageProfile{
Name: vdcStorageProfileDetails.Name,
Units: vdcStorageProfileDetails.Units,
Limit: vdcStorageProfileDetails.Limit,
Default: true,
Enabled: takeBoolPointer(true),
ProviderVdcStorageProfile: &types.Reference{
HREF: vdcStorageProfileDetails.ProviderVdcStorageProfile.HREF,
},
},
)
if err != nil {
return fmt.Errorf("cannot Set VDC default storage profile '%s': %s", storageProfileName, err)
dataclouder marked this conversation as resolved.
Show resolved Hide resolved
}
return vdc.Refresh()
}

// GetDefaultStorageProfileReference finds the default storage profile for the VDC
func (adminVdc *AdminVdc) GetDefaultStorageProfileReference() (*types.Reference, error) {
var defaultSp *types.Reference
if adminVdc.AdminVdc.VdcStorageProfiles == nil || adminVdc.AdminVdc.VdcStorageProfiles.VdcStorageProfile == nil {
return nil, fmt.Errorf("no storage profiles found in VDC %s", adminVdc.AdminVdc.Name)
}
for _, sp := range adminVdc.AdminVdc.VdcStorageProfiles.VdcStorageProfile {
fullSp, err := adminVdc.client.GetStorageProfileByHref(sp.HREF)
dataclouder marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return nil, fmt.Errorf("error retrieving storage profile %s for VDC %s: %s", sp.Name, adminVdc.AdminVdc.Name, err)
}
if fullSp.Default {
if defaultSp != nil {
return nil, fmt.Errorf("more than one default storage profile found for VDC %s: '%s' and '%s'", adminVdc.AdminVdc.Name, sp.Name, defaultSp.Name)
}
defaultSp = sp
}
}
if defaultSp != nil {
return defaultSp, nil
}
return nil, fmt.Errorf("no default storage profile found for VDC %s", adminVdc.AdminVdc.Name)
}
7 changes: 2 additions & 5 deletions govcd/adminvdc_nsxt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,10 @@ func (vcd *TestVCD) Test_CreateNsxtOrgVdc(check *C) {
}
providerVdcHref := pVdcs[0].HREF

pvdcStorageProfiles, err := QueryProviderVdcStorageProfileByName(vcd.client, vcd.config.VCD.NsxtProviderVdc.StorageProfile)
pvdcStorageProfile, err := vcd.client.QueryProviderVdcStorageProfileByName(vcd.config.VCD.NsxtProviderVdc.StorageProfile, providerVdcHref)

check.Assert(err, IsNil)
if len(pvdcStorageProfiles) == 0 {
check.Skip(fmt.Sprintf("No storage profile found with name '%s'", vcd.config.VCD.NsxtProviderVdc.StorageProfile))
}
providerVdcStorageProfileHref := pvdcStorageProfiles[0].HREF
providerVdcStorageProfileHref := pvdcStorageProfile.HREF

networkPools, err := QueryNetworkPoolByName(vcd.client, vcd.config.VCD.NsxtProviderVdc.NetworkPool)
check.Assert(err, IsNil)
Expand Down
9 changes: 6 additions & 3 deletions govcd/adminvdc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ func (vcd *TestVCD) Test_CreateOrgVdcWithFlex(check *C) {
check.Assert(adminOrg, NotNil)

providerVdcHref := getVdcProviderVdcHref(vcd, check)
providerVdcStorageProfileHref := getVdcProviderVdcStorageProfileHref(vcd, check)

storageProfile, err := vcd.client.QueryProviderVdcStorageProfileByName(vcd.config.VCD.ProviderVdc.StorageProfile, providerVdcHref)
check.Assert(err, IsNil)
providerVdcStorageProfileHref := storageProfile.HREF
networkPoolHref := getVdcNetworkPoolHref(vcd, check)

allocationModels := []string{"AllocationVApp", "AllocationPool", "ReservationPool", "Flex"}
Expand Down Expand Up @@ -208,7 +211,7 @@ func (vcd *TestVCD) Test_VdcUpdateStorageProfile(check *C) {
check.Assert(err, IsNil)
check.Assert(adminVdc, NotNil)

foundStorageProfile, err := GetStorageProfileByHref(vcd.client, adminVdc.AdminVdc.VdcStorageProfiles.VdcStorageProfile[0].HREF)
foundStorageProfile, err := vcd.client.Client.GetStorageProfileByHref(adminVdc.AdminVdc.VdcStorageProfiles.VdcStorageProfile[0].HREF)
check.Assert(err, IsNil)
check.Assert(foundStorageProfile, Not(Equals), types.VdcStorageProfile{})
check.Assert(foundStorageProfile, NotNil)
Expand All @@ -229,7 +232,7 @@ func (vcd *TestVCD) Test_VdcUpdateStorageProfile(check *C) {
check.Assert(err, IsNil)
check.Assert(updatedVdc, Not(IsNil))

updatedStorageProfile, err := GetStorageProfileByHref(vcd.client, adminVdc.AdminVdc.VdcStorageProfiles.VdcStorageProfile[0].HREF)
updatedStorageProfile, err := vcd.client.Client.GetStorageProfileByHref(adminVdc.AdminVdc.VdcStorageProfiles.VdcStorageProfile[0].HREF)
check.Assert(err, IsNil)
check.Assert(updatedStorageProfile, Not(Equals), types.VdcStorageProfile{})
check.Assert(updatedStorageProfile, NotNil)
Expand Down
2 changes: 1 addition & 1 deletion govcd/catalog.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func NewCatalog(client *Client) *Catalog {
}

// Delete deletes the Catalog, returning an error if the vCD call fails.
// Link to API call: https://code.vmware.com/apis/220/vcloud#/doc/doc/operations/DELETE-Catalog.html
// Link to API call: https://code.vmware.com/apis/1046/vmware-cloud-director/doc/doc/operations/DELETE-Catalog.html
func (catalog *Catalog) Delete(force, recursive bool) error {

adminCatalogHREF := catalog.client.VCDHREF
Expand Down
36 changes: 36 additions & 0 deletions govcd/catalogitem_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,3 +192,39 @@ func (vcd *TestVCD) TestQueryCatalogItemAndVAppTemplateList(check *C) {
}

}

func (vcd *TestVCD) Test_DeleteNonEmptyCatalog(check *C) {
skipWhenOvaPathMissing(vcd.config.OVA.OvaPath, check)

catalogName := check.TestName()
catalogItemName := check.TestName() + "_item"
// Fetching organization
org, err := vcd.client.GetAdminOrgByName(vcd.org.Org.Name)
check.Assert(err, IsNil)
check.Assert(org, NotNil)
catalog, err := org.CreateCatalog(catalogName, catalogName)
check.Assert(err, IsNil)
AddToCleanupList(catalogName, "catalog", vcd.org.Org.Name, check.TestName())

check.Assert(catalog, NotNil)

// add catalogItem
uploadTask, err := catalog.UploadOvf(vcd.config.OVA.OvaPath, catalogItemName, "upload from delete catalog item test", 1024)
check.Assert(err, IsNil)
err = uploadTask.WaitTaskCompletion()
check.Assert(err, IsNil)
AddToCleanupList(catalogItemName, "catalogItem", vcd.org.Org.Name+"|"+catalogName, check.TestName())

retrievedCatalog, err := org.GetCatalogByName(catalogName, true)
check.Assert(err, IsNil)
catalogItem, err := retrievedCatalog.GetCatalogItemByName(catalogItemName, true)
check.Assert(err, IsNil)
check.Assert(catalogItem, NotNil)

err = retrievedCatalog.Delete(true, true)
check.Assert(err, IsNil)

retrievedCatalog, err = org.GetCatalogByName(catalogName, true)
check.Assert(err, NotNil)
check.Assert(retrievedCatalog, IsNil)
}
19 changes: 3 additions & 16 deletions govcd/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -740,7 +740,8 @@ func spawnTestVdc(vcd *TestVCD, check *C, adminOrgName string) *Vdc {
check.Assert(err, IsNil)

providerVdcHref := getVdcProviderVdcHref(vcd, check)
providerVdcStorageProfileHref := getVdcProviderVdcStorageProfileHref(vcd, check)
storageProfile, err := vcd.client.QueryProviderVdcStorageProfileByName(vcd.config.VCD.ProviderVdc.StorageProfile, providerVdcHref)
check.Assert(err, IsNil)
networkPoolHref := getVdcNetworkPoolHref(vcd, check)

vdcConfiguration := &types.VdcConfiguration{
Expand All @@ -767,7 +768,7 @@ func spawnTestVdc(vcd *TestVCD, check *C, adminOrgName string) *Vdc {
Limit: 1024,
Default: true,
ProviderVdcStorageProfile: &types.Reference{
HREF: providerVdcStorageProfileHref,
HREF: storageProfile.HREF,
},
},
},
Expand Down Expand Up @@ -821,20 +822,6 @@ func getVdcProviderVdcHref(vcd *TestVCD, check *C) string {
return providerVdcHref
}

func getVdcProviderVdcStorageProfileHref(vcd *TestVCD, check *C) string {
results, err := vcd.client.QueryWithNotEncodedParams(nil, map[string]string{
"type": "providerVdcStorageProfile",
"filter": fmt.Sprintf("name==%s", vcd.config.VCD.ProviderVdc.StorageProfile),
})
check.Assert(err, IsNil)
if len(results.Results.ProviderVdcStorageProfileRecord) == 0 {
check.Skip(fmt.Sprintf("No storage profile found with name '%s'", vcd.config.VCD.ProviderVdc.StorageProfile))
}
providerVdcStorageProfileHref := results.Results.ProviderVdcStorageProfileRecord[0].HREF

return providerVdcStorageProfileHref
}

func getVdcNetworkPoolHref(vcd *TestVCD, check *C) string {
results, err := vcd.client.QueryWithNotEncodedParams(nil, map[string]string{
"type": "networkPool",
Expand Down
Loading