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

New functions for getting and updating Org vDC #206

Merged
merged 12 commits into from
Jul 1, 2019
1 change: 1 addition & 0 deletions govcd/api_vcd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ const (
TestUploadOvf = "TestUploadOvf"
TestDeleteCatalogItem = "TestDeleteCatalogItem"
TestCreateOrgVdc = "TestCreateOrgVdc"
TestRefreshOrgVdc = "TestRefreshOrgVdc"
TestCreateOrgVdcNetworkEGW = "TestCreateOrgVdcNetworkEGW"
TestCreateOrgVdcNetworkIso = "TestCreateOrgVdcNetworkIso"
TestCreateOrgVdcNetworkDirect = "TestCreateOrgVdcNetworkDirect"
Expand Down
78 changes: 78 additions & 0 deletions govcd/org.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,84 @@ func (org *Org) GetVdcByName(vdcname string) (Vdc, error) {
return Vdc{}, nil
}

// Given an adminVdc with a valid HREF, the function refresh the adminVdc
// and updates the adminVdc data. Otherwise if the function fails,
// it returns an error. Users should use refresh whenever they have
// a stale vDC due to the creation/update/deletion of a resource
// within the org or the vDC itself.
func (adminVdc *AdminVdc) Refresh() error {
dataclouder marked this conversation as resolved.
Show resolved Hide resolved
if *adminVdc == (AdminVdc{}) {
Didainius marked this conversation as resolved.
Show resolved Hide resolved
return fmt.Errorf("cannot refresh, Object is empty")
}

// Empty struct before a new unmarshal, otherwise we end up with duplicate
// elements in slices.
unmarshalledAdminVdc := &types.AdminVdc{}

_, err := adminVdc.client.ExecuteRequest(adminVdc.AdminVdc.HREF, http.MethodGet,
"", "error refreshing vDC: %s", nil, unmarshalledAdminVdc)
if err != nil {
return err
}
adminVdc.AdminVdc = unmarshalledAdminVdc

return nil
}

// GetAdminVdcByName function uses user specifies valid vdc name and then returns a admin vDC object.
dataclouder marked this conversation as resolved.
Show resolved Hide resolved
// If no vDC is found, then it returns an empty vDC and no error.
// Otherwise it returns an empty vDC and an error.
func (adminOrg *AdminOrg) GetAdminVdcByName(vdcname string) (AdminVdc, error) {
for _, vdcs := range adminOrg.AdminOrg.Vdcs.Vdcs {
if vdcs.Name == vdcname {

adminVdc := NewAdminVdc(adminOrg.client)

_, err := adminOrg.client.ExecuteRequest(vdcs.HREF, http.MethodGet,
"", "error getting vdc: %s", nil, adminVdc.AdminVdc)

return *adminVdc, err
}
}
return AdminVdc{}, nil
}

// Function UpdateAsync() updated vCD from current vCD struct contents.
dataclouder marked this conversation as resolved.
Show resolved Hide resolved
// Any differences that may be legally applied will be updated.
// Returns an error if the call to vCD fails.
// API Documentation: https://vdc-repo.vmware.com/vmwb-repository/dcr-public/7a028e78-bd37-4a6a-8298-9c26c7eeb9aa/09142237-dd46-4dee-8326-e07212fb63a8/doc/doc/operations/PUT-Vdc.html
func (adminVdc *AdminVdc) UpdateAsync() (Task, error) {

adminVdc.AdminVdc.Xmlns = types.XMLNamespaceVCloud

// Return the task
return adminVdc.client.ExecuteTaskRequest(adminVdc.AdminVdc.HREF, http.MethodPut,
types.MimeAdminVDC, "error updating vDC: %s", adminVdc.AdminVdc)
}

// Function Update() updated vCD from current vCD struct contents.
dataclouder marked this conversation as resolved.
Show resolved Hide resolved
// Any differences that may be legally applied will be updated.
// Returns an empty AdminVdc struct and error if the call to vCD fails.
// API Documentation: https://vdc-repo.vmware.com/vmwb-repository/dcr-public/7a028e78-bd37-4a6a-8298-9c26c7eeb9aa/09142237-dd46-4dee-8326-e07212fb63a8/doc/doc/operations/PUT-Vdc.html
func (adminVdc *AdminVdc) Update() (AdminVdc, error) {
task, err := adminVdc.UpdateAsync()
if err != nil {
return AdminVdc{}, err
}

err = task.WaitTaskCompletion()
if err != nil {
return AdminVdc{}, err
}

err = adminVdc.Refresh()
if err != nil {
return AdminVdc{}, err
}

return *adminVdc, nil
}

// AdminOrg gives an admin representation of an org.
// Administrators can delete and update orgs with an admin org object.
// AdminOrg includes all members of the Org element, and adds several
Expand Down
210 changes: 210 additions & 0 deletions govcd/org_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -420,3 +420,213 @@ func (vcd *TestVCD) Test_GetAdminCatalog(check *C) {
check.Assert(cat.AdminCatalog.Description, Equals, vcd.config.VCD.Catalog.Description)
}
}

// Tests Refresh for Vdc by updating the Vdc and then asserting if the
dataclouder marked this conversation as resolved.
Show resolved Hide resolved
// variable is updated.
func (vcd *TestVCD) Test_RefreshVdc(check *C) {

adminOrg, err, vdcConfiguration := setupVDc(vcd, check)

// Refresh so the new VDC shows up in the org's list
err = adminOrg.Refresh()
check.Assert(err, IsNil)

adminVdc, err := adminOrg.GetAdminVdcByName(vdcConfiguration.Name)

check.Assert(err, IsNil)
check.Assert(adminVdc, Not(Equals), Vdc{})
check.Assert(adminVdc.AdminVdc.Name, Equals, vdcConfiguration.Name)
check.Assert(adminVdc.AdminVdc.IsEnabled, Equals, vdcConfiguration.IsEnabled)
check.Assert(adminVdc.AdminVdc.AllocationModel, Equals, vdcConfiguration.AllocationModel)

adminVdc.AdminVdc.Name = TestRefreshOrgVdc
_, err = adminVdc.Update()
check.Assert(err, IsNil)
AddToCleanupList(TestRefreshOrgVdc, "vdc", vcd.org.Org.Name, check.TestName())

// Test Refresh on vdc
err = adminVdc.Refresh()
check.Assert(err, IsNil)
check.Assert(adminVdc.AdminVdc.Name, Equals, TestRefreshOrgVdc)
}

func setupVDc(vcd *TestVCD, check *C) (AdminOrg, error, *types.VdcConfiguration) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
func setupVDc(vcd *TestVCD, check *C) (AdminOrg, error, *types.VdcConfiguration) {
func setupVDc(vcd *TestVCD, check *C) (AdminOrg, *types.VdcConfiguration, error) {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

if vcd.skipAdminTests {
check.Skip(fmt.Sprintf(TestRequiresSysAdminPrivileges, check.TestName()))
}
if vcd.config.VCD.ProviderVdc.Name == "" {
check.Skip("No Provider VDC name given for VDC tests")
}
if vcd.config.VCD.ProviderVdc.StorageProfile == "" {
check.Skip("No Storage Profile given for VDC tests")
}
if vcd.config.VCD.ProviderVdc.NetworkPool == "" {
check.Skip("No Network Pool given for VDC tests")
}
adminOrg, err := GetAdminOrgByName(vcd.client, vcd.org.Org.Name)
check.Assert(err, IsNil)
check.Assert(adminOrg, Not(Equals), AdminOrg{})
results, err := vcd.client.QueryWithNotEncodedParams(nil, map[string]string{
"type": "providerVdc",
"filter": fmt.Sprintf("(name==%s)", vcd.config.VCD.ProviderVdc.Name),
})
check.Assert(err, IsNil)
if len(results.Results.VMWProviderVdcRecord) == 0 {
check.Skip(fmt.Sprintf("No Provider VDC found with name '%s'", vcd.config.VCD.ProviderVdc.Name))
}
providerVdcHref := results.Results.VMWProviderVdcRecord[0].HREF
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
results, err = vcd.client.QueryWithNotEncodedParams(nil, map[string]string{
"type": "networkPool",
"filter": fmt.Sprintf("(name==%s)", vcd.config.VCD.ProviderVdc.NetworkPool),
})
check.Assert(err, IsNil)
if len(results.Results.NetworkPoolRecord) == 0 {
check.Skip(fmt.Sprintf("No network pool found with name '%s'", vcd.config.VCD.ProviderVdc.NetworkPool))
}
networkPoolHref := results.Results.NetworkPoolRecord[0].HREF
vdcConfiguration := &types.VdcConfiguration{
Name: TestCreateOrgVdc + "ForRefresh",
Xmlns: types.XMLNamespaceVCloud,
AllocationModel: "AllocationPool",
ComputeCapacity: []*types.ComputeCapacity{
&types.ComputeCapacity{
CPU: &types.CapacityWithUsage{
Units: "MHz",
Allocated: 1024,
Limit: 1024,
},
Memory: &types.CapacityWithUsage{
Allocated: 1024,
Limit: 1024,
Units: "MB",
},
},
},
VdcStorageProfile: []*types.VdcStorageProfile{&types.VdcStorageProfile{
Enabled: true,
Units: "MB",
Limit: 1024,
Default: true,
ProviderVdcStorageProfile: &types.Reference{
HREF: providerVdcStorageProfileHref,
},
},
},
NetworkPoolReference: &types.Reference{
HREF: networkPoolHref,
},
ProviderVdcReference: &types.Reference{
HREF: providerVdcHref,
},
IsEnabled: true,
IsThinProvision: true,
UsesFastProvisioning: true,
}
vdc, err := adminOrg.GetVdcByName(vdcConfiguration.Name)
check.Assert(err, IsNil)
if vdc != (Vdc{}) {
err = vdc.DeleteWait(true, true)
check.Assert(err, IsNil)
}
err = adminOrg.CreateVdcWait(vdcConfiguration)
check.Assert(err, IsNil)
AddToCleanupList(vdcConfiguration.Name, "vdc", vcd.org.Org.Name, check.TestName())
return adminOrg, err, vdcConfiguration
}

// Tests Vdc by updating the Vdc and then asserting if the
dataclouder marked this conversation as resolved.
Show resolved Hide resolved
// variable is updated.
func (vcd *TestVCD) Test_UpdateVdc(check *C) {
adminOrg, err, vdcConfiguration := setupVDc(vcd, check)

// Refresh so the new VDC shows up in the org's list
err = adminOrg.Refresh()
check.Assert(err, IsNil)

adminVdc, err := adminOrg.GetAdminVdcByName(vdcConfiguration.Name)

check.Assert(err, IsNil)
check.Assert(adminVdc, Not(Equals), Vdc{})
check.Assert(adminVdc.AdminVdc.Name, Equals, vdcConfiguration.Name)
check.Assert(adminVdc.AdminVdc.IsEnabled, Equals, vdcConfiguration.IsEnabled)
check.Assert(adminVdc.AdminVdc.AllocationModel, Equals, vdcConfiguration.AllocationModel)

updateDescription := "updateDescription"
computeCapacity := []*types.ComputeCapacity{
&types.ComputeCapacity{
CPU: &types.CapacityWithUsage{
Units: "MHz",
Allocated: 2024,
Limit: 2024,
},
Memory: &types.CapacityWithUsage{
Allocated: 2024,
Limit: 2024,
Units: "MB",
},
},
}
quota := 111
vCpu := int64(1000)
guaranteed := float64(0.6)
adminVdc.AdminVdc.Description = updateDescription
adminVdc.AdminVdc.ComputeCapacity = computeCapacity
adminVdc.AdminVdc.IsEnabled = false
adminVdc.AdminVdc.IsThinProvision = false
adminVdc.AdminVdc.NetworkQuota = quota
adminVdc.AdminVdc.VMQuota = quota
adminVdc.AdminVdc.OverCommitAllowed = false
adminVdc.AdminVdc.VCpuInMhz = vCpu
adminVdc.AdminVdc.UsesFastProvisioning = false
adminVdc.AdminVdc.ResourceGuaranteedCpu = guaranteed
adminVdc.AdminVdc.ResourceGuaranteedMemory = guaranteed

updatedVdc, err := adminVdc.Update()
check.Assert(err, IsNil)
check.Assert(updatedVdc, Not(IsNil))
check.Assert(updatedVdc.AdminVdc.Description, Equals, updateDescription)
check.Assert(updatedVdc.AdminVdc.ComputeCapacity[0].CPU.Allocated, Equals, computeCapacity[0].CPU.Allocated)
check.Assert(updatedVdc.AdminVdc.IsEnabled, Equals, false)
check.Assert(updatedVdc.AdminVdc.IsThinProvision, Equals, false)
check.Assert(updatedVdc.AdminVdc.NetworkQuota, Equals, quota)
check.Assert(updatedVdc.AdminVdc.VMQuota, Equals, quota)
check.Assert(updatedVdc.AdminVdc.OverCommitAllowed, Equals, false)
check.Assert(updatedVdc.AdminVdc.VCpuInMhz, Equals, vCpu)
check.Assert(updatedVdc.AdminVdc.UsesFastProvisioning, Equals, false)
check.Assert(updatedVdc.AdminVdc.ResourceGuaranteedCpu, Equals, guaranteed)
Didainius marked this conversation as resolved.
Show resolved Hide resolved
check.Assert(updatedVdc.AdminVdc.ResourceGuaranteedMemory, Equals, guaranteed)
}

// Tests org function GetAdminVdcByName with the vdc specified
// in the config file. Then tests with a vdc that doesn't exist.
// Fails if the config file name doesn't match with the found vDC, or
// if the invalid vDC is found by the function. Also tests an vDC
// that doesn't exist. Asserts an error if the function finds it or
// if the error is not nil.
func (vcd *TestVCD) Test_GetAdminVdcByName(check *C) {
if vcd.skipAdminTests {
check.Skip(fmt.Sprintf(TestRequiresSysAdminPrivileges, check.TestName()))
}

adminOrg, err := GetAdminOrgByName(vcd.client, vcd.org.Org.Name)
check.Assert(err, IsNil)
check.Assert(adminOrg, Not(Equals), AdminOrg{})

adminVdc, err := adminOrg.GetAdminVdcByName(vcd.config.VCD.Vdc)
check.Assert(adminVdc, Not(Equals), AdminVdc{})
check.Assert(err, IsNil)
check.Assert(adminVdc.AdminVdc.Name, Equals, vcd.config.VCD.Vdc)
// Try a vdc that doesn't exist
adminVdc, err = adminOrg.GetAdminVdcByName(INVALID_NAME)
check.Assert(adminVdc, Equals, AdminVdc{})
check.Assert(err, IsNil)
}
2 changes: 2 additions & 0 deletions types/v56/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ const (
MimeCatalogItem = "application/vnd.vmware.vcloud.catalogItem+xml"
// MimeVDC mime for a VDC
MimeVDC = "application/vnd.vmware.vcloud.vdc+xml"
// MimeVDC mime for a admin VDC
MimeAdminVDC = "application/vnd.vmware.admin.vdc+xml"
// MimeVAppTemplate mime for a vapp template
MimeVAppTemplate = "application/vnd.vmware.vcloud.vAppTemplate+xml"
// MimeVApp mime for a vApp
Expand Down
Loading