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 AdminOrgVdcStorageProfile for querying #375

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 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
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@
[#368](https://github.com/vmware/go-vcloud-director/pull/368)
* Added methods Org.QueryVmList and Org.QueryVmById to find VM by ID in an Org
[#368](https://github.com/vmware/go-vcloud-director/pull/368)
* Added support for querying VdcStorageProfile:
- functions `QueryAdminOrgVdcStorageProfileByID` and `QueryOrgVdcStorageProfileByID`
- query types `QtOrgVdcStorageProfile` and `QtAdminOrgVdcStorageProfile`
- data struct `QueryResultAdminOrgVdcStorageProfileRecordType` (non admin struct already was here)
[#373](https://github.com/vmware/go-vcloud-director/issues/373)

BREAKING CHANGES:
* Added parameter `description` to method `vdc.ComposeRawVapp` [#372](https://github.com/vmware/go-vcloud-director/pull/372)
Expand Down
5 changes: 3 additions & 2 deletions govcd/api_vcd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,9 @@ type TestConfig struct {
Net2 string `yaml:"network2,omitempty"`
} `yaml:"network"`
StorageProfile struct {
SP1 string `yaml:"storageProfile1"`
SP2 string `yaml:"storageProfile2,omitempty"`
SP1 string `yaml:"storageProfile1"`
SP1ID string `yaml:"storageProfile1ID"`
SP2 string `yaml:"storageProfile2,omitempty"`
} `yaml:"storageProfile"`
ExternalIp string `yaml:"externalIp,omitempty"`
ExternalNetmask string `yaml:"externalNetmask,omitempty"`
Expand Down
2 changes: 2 additions & 0 deletions govcd/sample_govcd_test_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ vcd:
storageProfile:
# First storage profile (mandatory)
storageProfile1: Development
# ID of storage profile. If omitted, some tests will be skipped.
storageProfile1ID: 8263c1b5-6a40-404f-84a3-72343fce7c20
lelvisl marked this conversation as resolved.
Show resolved Hide resolved
# Second storage profile. If omitted, some tests will be skipped.
storageProfile2: "*"
# An edge gateway
Expand Down
26 changes: 26 additions & 0 deletions govcd/system.go
Original file line number Diff line number Diff line change
Expand Up @@ -975,3 +975,29 @@ func (vcdCli *VCDClient) GetOrgList() (*types.OrgList, error) {
}
return orgList, nil
}

// QueryAdminOrgVdcStorageProfileByID finds a StorageProfile of VDC by ID as admin
func QueryAdminOrgVdcStorageProfileByID(vcdCli *VCDClient, id string) ([]*types.QueryResultAdminOrgVdcStorageProfileRecordType, error) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Thanks for this. Now just pardon, but I just tried to play with code and one thing hit me.
I think the signature could be:

Suggested change
func QueryAdminOrgVdcStorageProfileByID(vcdCli *VCDClient, id string) ([]*types.QueryResultAdminOrgVdcStorageProfileRecordType, error) {
func QueryAdminOrgVdcStorageProfileByID(vcdCli *VCDClient, id string) (*types.QueryResultAdminOrgVdcStorageProfileRecordType, error) {

That is - you don't need to return a slice of results because you are querying by ID which guarantees that there is either exactly one result, or not.

A slice could be if it was QueryOrgVdcStorageProfile which doesn't guarantee one object.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Can i then rename this method to GetAdminOrgVdcStorageProfileByID?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Or implement QueryOrgVdcStorageProfile with params and GetAdminOrgVdcStorageProfileByID that use previous?

Copy link
Collaborator

Choose a reason for hiding this comment

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

GetX in this SDK usually mean that it is not an object from query endpoint, but from its legitimate endpoint (e.g. AdminOrg.GetVDCById would not return a Query result, but the VDC struct itself. Query and object endpoints usually return different data that is why we try to keep Query and Get (to differentiate these things). This is not 100% due to historic reasons, but that is a good thing to follow.

Or - if you want to implement a function that returns all objects then it could be QueryAdminOrgVdcStorageProfile. But if you simply leave the code as it is (and not apply ID filter) you will hit a problem - by default it returns only the first page of data (which is usually up to 25 items). It is not easy to spot this on testing envs where not many resources exist, but we have already hit that and fixed some of the problems here. The trick here is to use client.cumulativeQuery internally which handles pagination and makes sure all pages are retrieved. (You could look through functions like QueryEdgeGatewayList or QueryAllVdcs to see how it is implemented.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agree with you and changed signature.

About QueryAdminOrgVdcStorageProfile - i think we need separate issue for discuss.

results, err := vcdCli.QueryWithNotEncodedParams(nil, map[string]string{
"type": types.QtAdminOrgVdcStorageProfile,
"filter": fmt.Sprintf("id==%s", url.QueryEscape(id)),
"filterEncoded": "true",
})
if err != nil {
return nil, err
}
return results.Results.AdminOrgVdcStorageProfileRecord, nil
}

// QueryOrgVdcStorageProfileByID finds a StorageProfile of VDC by ID
func QueryOrgVdcStorageProfileByID(vcdCli *VCDClient, id string) ([]*types.QueryResultOrgVdcStorageProfileRecordType, error) {
results, err := vcdCli.QueryWithNotEncodedParams(nil, map[string]string{
"type": types.QtOrgVdcStorageProfile,
"filter": fmt.Sprintf("id==%s", url.QueryEscape(id)),
"filterEncoded": "true",
})
if err != nil {
return nil, err
}
return results.Results.OrgVdcStorageProfileRecord, nil
}
26 changes: 26 additions & 0 deletions govcd/system_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,32 @@ func (vcd *TestVCD) Test_QueryProviderVdcByName(check *C) {

}

func (vcd *TestVCD) Test_QueryAdminOrgVdcStorageProfileByID(check *C) {
if vcd.config.VCD.StorageProfile.SP1ID == "" {
check.Skip("Skipping VDC StorageProfile query: no StorageProfile ID was given")
}
vdcStorageProfiles, err := QueryAdminOrgVdcStorageProfileByID(vcd.client, vcd.config.VCD.StorageProfile.SP1ID)
check.Assert(err, IsNil)
check.Assert(len(vdcStorageProfiles) > 0, Equals, true)

storageProfileFound := false
href := vcd.client.Client.VCDHREF
href.Path += "/admin/vdcStorageProfile/" + vcd.config.VCD.StorageProfile.SP1ID
for _, vdcStorageProfile := range vdcStorageProfiles {
if href.String() == vdcStorageProfile.HREF {
storageProfileFound = true
}

if testVerbose {
fmt.Printf("StorageProfile %s\n", vdcStorageProfile.Name)
fmt.Printf("\t href %s\n", vdcStorageProfile.HREF)
fmt.Printf("\t enabled %v\n", vdcStorageProfile.IsEnabled)
fmt.Println("")
}
}
check.Assert(storageProfileFound, Equals, true)
}

func (vcd *TestVCD) Test_QueryNetworkPoolByName(check *C) {
if vcd.config.VCD.ProviderVdc.NetworkPool == "" {
check.Skip("Skipping Provider VDC network pool query: no provider VDC network pool was given")
Expand Down
34 changes: 18 additions & 16 deletions types/v56/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,22 +236,24 @@ const (

const (
// The Qt* (Query Type) constants are the names used with Query requests to retrieve the corresponding entities
QtVappTemplate = "vAppTemplate" // vApp template
QtAdminVappTemplate = "adminVAppTemplate" // vApp template as admin
QtEdgeGateway = "edgeGateway" // edge gateway
QtOrgVdcNetwork = "orgVdcNetwork" // Org VDC network
QtCatalog = "catalog" // catalog
QtAdminCatalog = "adminCatalog" // catalog as admin
QtCatalogItem = "catalogItem" // catalog item
QtAdminCatalogItem = "adminCatalogItem" // catalog item as admin
QtAdminMedia = "adminMedia" // media item as admin
QtMedia = "media" // media item
QtVm = "vm" // Virtual machine
QtAdminVm = "adminVM" // Virtual machine as admin
QtVapp = "vApp" // vApp
QtAdminVapp = "adminVApp" // vApp as admin
QtOrgVdc = "orgVdc" // Org VDC
QtAdminOrgVdc = "adminOrgVdc" // Org VDC as admin
QtVappTemplate = "vAppTemplate" // vApp template
QtAdminVappTemplate = "adminVAppTemplate" // vApp template as admin
QtEdgeGateway = "edgeGateway" // edge gateway
QtOrgVdcNetwork = "orgVdcNetwork" // Org VDC network
QtCatalog = "catalog" // catalog
QtAdminCatalog = "adminCatalog" // catalog as admin
QtCatalogItem = "catalogItem" // catalog item
QtAdminCatalogItem = "adminCatalogItem" // catalog item as admin
QtAdminMedia = "adminMedia" // media item as admin
QtMedia = "media" // media item
QtVm = "vm" // Virtual machine
QtAdminVm = "adminVM" // Virtual machine as admin
QtVapp = "vApp" // vApp
QtAdminVapp = "adminVApp" // vApp as admin
QtOrgVdc = "orgVdc" // Org VDC
QtAdminOrgVdc = "adminOrgVdc" // Org VDC as admin
QtOrgVdcStorageProfile = "orgVdcStorageProfile" // StorageProfile of VDC
QtAdminOrgVdcStorageProfile = "adminOrgVdcStorageProfile" // StorageProfile of VDC as admin
)

// AdminQueryTypes returns the corresponding "admin" query type for each regular type
Expand Down
26 changes: 26 additions & 0 deletions types/v56/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -2147,6 +2147,7 @@ type QueryResultRecordsType struct {
VAppRecord []*QueryResultVAppRecordType `xml:"VAppRecord"` // A record representing a VApp result.
AdminVAppRecord []*QueryResultVAppRecordType `xml:"AdminVAppRecord"` // A record representing a VApp result as admin.
OrgVdcStorageProfileRecord []*QueryResultOrgVdcStorageProfileRecordType `xml:"OrgVdcStorageProfileRecord"` // A record representing storage profiles
AdminOrgVdcStorageProfileRecord []*QueryResultAdminOrgVdcStorageProfileRecordType `xml:"AdminOrgVdcStorageProfileRecord"` // A record Admin representing storage profiles
MediaRecord []*MediaRecordType `xml:"MediaRecord"` // A record representing media
AdminMediaRecord []*MediaRecordType `xml:"AdminMediaRecord"` // A record representing Admin media
VMWProviderVdcRecord []*QueryResultVMWProviderVdcRecordType `xml:"VMWProviderVdcRecord"` // A record representing a Provider VDC result.
Expand Down Expand Up @@ -2386,6 +2387,31 @@ type QueryResultOrgVdcStorageProfileRecordType struct {
StorageLimitMB int `xml:"storageLimitMB,attr,omitempty"`
}

// QueryResultAdminOrgVdcStorageProfileRecordType represents a storage
// profile as query result.
// https://code.vmware.com/apis/722/vmware-cloud-director/doc/doc/types/QueryResultAdminOrgVdcStorageProfileRecordType.html
type QueryResultAdminOrgVdcStorageProfileRecordType struct {
// Attributes
HREF string `xml:"href,attr,omitempty"` // The URI of the entity.
ID string `xml:"id,attr,omitempty"` // The ID of the entity.
Type string `xml:"type,attr,omitempty"` // Contains the type of the resource.
Name string `xml:"name,attr,omitempty"` // Name of the storage profile.
IsEnabled bool `xml:"isEnabled,attr,omitempty"` // True if this entity is enabled.
IsDefaultStorageProfile bool `xml:"isDefaultStorageProfile,attr,omitempty"` // True if this is the default storage profile for a VDC.
StorageUsedMB uint64 `xml:"storageUsedMB,attr,omitempty"` // Storage used in MB.
StorageLimitMB uint64 `xml:"storageLimitMB,attr,omitempty"` // Storage limit in MB.
IopsAllocated uint64 `xml:"iopsAllocated,attr,omitempty"` // Total currently allocated IOPS on the storage profile.
IopsLimit uint64 `xml:"iopsLimit,attr,omitempty"` // IOPS limit for the storage profile.
NumberOfConditions int `xml:"numberOfConditions,attr,omitempty"` // Number of conditions on the storage profile.
Vdc string `xml:"vdc,attr,omitempty"` // VDC reference or id.
VdcName string `xml:"vdcName,attr,omitempty"` // VDC name.
Org string `xml:"isVdcBusy,attr,omitempty"` // Organization reference or id.
VC string `xml:"vc,attr,omitempty"` // Virtual center reference or id.
// Elements
Link []*Link `xml:"Link,omitempty"`
MetadataEntry []*MetadataEntry `xml:"MetadataEntry,omitempty"`
}

// QueryResultVMWProviderVdcRecordType represents a Provider VDC as query result.
type QueryResultVMWProviderVdcRecordType struct {
// Attributes
Expand Down