Skip to content

Commit

Permalink
Site and org associations (#669)
Browse files Browse the repository at this point in the history
* Enable query for Organizations
* Add types and basic methods to retrieve associations
* Update cumulative query for Orgs
* Add functions to get associations data from site and organization
* Add methods to set and remove Org associations
* Add functions to set/remove site associations
* Add type Site
* Add methods GetSite, CheckSiteAssociation, CheckOrgAssociation
* Add full multi-site test
* Add method AdminOrg.GetAllOpenApiOrgVdcNetworks
* Add method client.GetAllOrgs for multi-site retrieval of organizations
* Add changelog entry

---------

Signed-off-by: Giuseppe Maxia <giuseppe.maxia@broadcom.com>
Co-authored-by: Roman Hochuli <roman.hochuli@netrics.ch>
  • Loading branch information
dataclouder and Roman Hochuli committed Jun 24, 2024
1 parent a3c4900 commit 6bcb3f4
Show file tree
Hide file tree
Showing 18 changed files with 1,267 additions and 20 deletions.
16 changes: 16 additions & 0 deletions .changes/v2.25.0/669-features.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
* Added `Client` method `GetSite` to retrieve generic data about the current site [GH-669]
* Added `Client` methods `GetSiteAssociationData` and `GetSiteRawAssociationData` to retrieve association about from current site [GH-669]
* Added `Client` methods `GetSiteAssociations` and `QueryAllSiteAssociations` to retrieve all site associations from current site [GH-669]
* Added `Client` method `GetSiteAssociationBySiteId` to retrieve a specific site association from current site [GH-669]
* Added `Client` method `CheckSiteAssociation` to check the status of a site association [GH-669]
* Added `Client` methods `SetSiteAssociationAsync` and `SetSiteAssociation` to set a site association with current site [GH-669]
* Added `Client` methods `RemoveSiteAssociationAsync` and `RemoveSiteAssociation` to delete a site association from current site [GH-669]
* Added `Client` method `QueryAllOrgAssociations` and `GetOrgAssociations` to retrieve all org associations visible to current user [GH-669]
* Added `AdminOrg` method `GetOrgAssociationByOrgId` to retrieve a specific organization association from current org [GH-669]
* Added `AdminOrg` methods `GetOrgAssociationData` and `GetOrgRawAssociationData` to retrieve association about from current org [GH-669]
* Added `AdminOrg` method `CheckOrgAssociation` to check the status of an org association [GH-669]
* Added `AdminOrg` methods `SetOrgAssociationAsync` and `SetOrgAssociation` to set an organization association with current org [GH-669]
* Added `AdminOrg` methods `RemoveOrgAssociationAsync` and `RemoveOrgAssociation` to delete an organization association from current org [GH-669]
* Added function `RawDataToStructuredXml` and `ReadXmlDataFromFile` to extract specific data from string or file [GH-669]
* Added `AdminOrg` methods `QueryAllOrgs`, `QueryOrgByName`, `QueryOrgByID` to query organizations [GH-612,GH-669]
* Added `AdminOrg` methods `GetAllOrgs` and `GetAllOpenApiOrgVdcNetworks` to retrieve organizations and networks available to current user [GH-669]
31 changes: 19 additions & 12 deletions govcd/api_vcd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2064,16 +2064,25 @@ func skipOpenApiEndpointTest(vcd *TestVCD, check *C, endpoint string) {
}
}

// newOrgUserConnection creates a new Org User and returns a connection to it.
// Attention: Set the user to use only lowercase letters. If you put upper case letters the function fails on waiting
// because VCD creates the user with lowercase letters.
func newOrgUserConnection(adminOrg *AdminOrg, userName, password, href string, insecure bool) (*VCDClient, *OrgUser, error) {
// newUserConnection returns a connection for a given user
func newUserConnection(href, userName, password, orgName string, insecure bool) (*VCDClient, error) {
u, err := url.ParseRequestURI(href)
if err != nil {
return nil, nil, fmt.Errorf("[newOrgUserConnection] unable to pass url: %s", err)
return nil, fmt.Errorf("[newUserConnection] unable to pass url: %s", err)
}
vcdClient := NewVCDClient(*u, insecure)
err = vcdClient.Authenticate(userName, password, orgName)
if err != nil {
return nil, fmt.Errorf("[newUserConnection] unable to authenticate: %s", err)
}
return vcdClient, nil
}

_, err = adminOrg.GetUserByName(userName, false)
// newOrgUserConnection creates a new Org User and returns a connection to it.
// Attention: Set the user to use only lowercase letters. If you put upper case letters the function fails on waiting
// because VCD creates the user with lowercase letters.
func newOrgUserConnection(adminOrg *AdminOrg, userName, password, href string, insecure bool) (*VCDClient, *OrgUser, error) {
_, err := adminOrg.GetUserByName(userName, false)
if err == nil {
// user exists
return nil, nil, fmt.Errorf("user %s already exists", userName)
Expand All @@ -2096,16 +2105,14 @@ func newOrgUserConnection(adminOrg *AdminOrg, userName, password, href string, i
AddToCleanupList(userName, "user", adminOrg.AdminOrg.Name, "newOrgUserConnection")

_ = adminOrg.Refresh()
vcdClient := NewVCDClient(*u, insecure)
err = vcdClient.Authenticate(userName, password, adminOrg.AdminOrg.Name)
newUser, err := adminOrg.GetUserByName(userName, false)
if err != nil {
return nil, nil, fmt.Errorf("[newOrgUserConnection] unable to authenticate: %s", err)
return nil, nil, fmt.Errorf("[newOrgUserConnection] unable to retrieve newly created user: %s", err)
}

// return newUser
newUser, err := adminOrg.GetUserByName(userName, false)
vcdClient, err := newUserConnection(href, userName, password, adminOrg.AdminOrg.Name, insecure)
if err != nil {
return nil, nil, fmt.Errorf("[newOrgUserConnection] unable to retrieve newly created user: %s", err)
return nil, nil, fmt.Errorf("[newOrgUserConnection] error connecting new user: %s", err)
}

return vcdClient, newUser, nil
Expand Down
2 changes: 1 addition & 1 deletion govcd/cse_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ func cseConvertToCseKubernetesClusterType(rde *DefinedEntity) (*CseKubernetesClu
params.Add("filter", fmt.Sprintf("name==%s", result.capvcdType.Status.Capvcd.VcdProperties.OrgVdcs[0].OvdcNetworkName))
params = queryParameterFilterAnd("orgVdc.id=="+result.VdcId, params)
params = queryParameterFilterAnd("_context==includeAccessible", params)
networks, err := getAllOpenApiOrgVdcNetworks(rde.client, params)
networks, err := getAllOpenApiOrgVdcNetworks(rde.client, params, nil)
if err != nil {
return nil, fmt.Errorf("could not read Org VDC Network from Capvcd type: %s", err)
}
Expand Down
19 changes: 19 additions & 0 deletions govcd/filter_interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ type (
QueryOrgVdc types.QueryResultOrgVdcRecordType
QueryTask types.QueryResultTaskRecordType
QueryAdminTask types.QueryResultTaskRecordType
QueryOrg types.QueryResultOrgRecordType
)

// getMetadataValue is a generic metadata lookup for all query items
Expand Down Expand Up @@ -230,6 +231,20 @@ func (vm QueryVm) GetMetadataValue(key string) string {
return getMetadataValue(vm.MetaData, key)
}

// --------------------------------------------------------------
// Organization
// --------------------------------------------------------------
func (org QueryOrg) GetHref() string { return org.HREF }
func (org QueryOrg) GetName() string { return org.Name }
func (org QueryOrg) GetType() string { return "organization" }
func (org QueryOrg) GetDate() string { return "" }
func (org QueryOrg) GetIp() string { return "" }
func (org QueryOrg) GetParentId() string { return "" }
func (org QueryOrg) GetParentName() string { return "" }
func (org QueryOrg) GetMetadataValue(key string) string {
return getMetadataValue(org.Metadata, key)
}

// --------------------------------------------------------------
// result conversion
// --------------------------------------------------------------
Expand Down Expand Up @@ -273,6 +288,10 @@ func resultToQueryItems(queryType string, results Results) ([]QueryItem, error)
for i, item := range results.Results.OrgVdcNetworkRecord {
items[i] = QueryOrgVdcNetwork(*item)
}
case types.QtOrg:
for i, item := range results.Results.OrgRecord {
items[i] = QueryOrg(*item)
}
case types.QtCatalog:
for i, item := range results.Results.CatalogRecord {
items[i] = QueryCatalog(*item)
Expand Down
Loading

0 comments on commit 6bcb3f4

Please sign in to comment.