diff --git a/.changes/v2.18.0/531-features.md b/.changes/v2.18.0/531-features.md new file mode 100644 index 000000000..d77f99488 --- /dev/null +++ b/.changes/v2.18.0/531-features.md @@ -0,0 +1 @@ +* Added `client` methods `QueryCatalogRecords` and `GetCatalogByHref` [GH-531] diff --git a/govcd/access_control_catalog_test.go b/govcd/access_control_catalog_test.go index 4853d4ec0..e66eda8d1 100644 --- a/govcd/access_control_catalog_test.go +++ b/govcd/access_control_catalog_test.go @@ -351,6 +351,12 @@ func (vcd *TestVCD) testCatalogAccessControl(adminOrg *AdminOrg, catalog accessC } err = testAccessControl(catalogName+" catalog two org", catalog, twoOrgsSettings, twoOrgsSettings, true, catalogTenantContext, check) check.Assert(err, IsNil) + catalogs, err := vcd.client.Client.QueryCatalogRecords(catalogName, TenantContext{newOrg.AdminOrg.ID, newOrg.AdminOrg.Name}) + check.Assert(err, IsNil) + check.Assert(len(catalogs), Equals, 1) + foundCatalog, err := vcd.client.Client.GetCatalogByHref(catalogs[0].HREF) + check.Assert(err, IsNil) + check.Assert(foundCatalog.AdminCatalog.ID, Equals, catalog.GetId()) } // Set empty settings explicitly diff --git a/govcd/admincatalog.go b/govcd/admincatalog.go index 47a4558be..0d331d263 100644 --- a/govcd/admincatalog.go +++ b/govcd/admincatalog.go @@ -627,3 +627,56 @@ func (catalog *AdminCatalog) QueryTaskList(filter map[string]string) ([]*types.Q filter["object"] = catalogHref return catalog.client.QueryTaskList(filter) } + +// GetCatalogByHref allows retrieving a catalog from HREF, without its parent +func (client *Client) GetCatalogByHref(catalogHref string) (*AdminCatalog, error) { + catalogHref = strings.Replace(catalogHref, "/api/catalog", "/api/admin/catalog", 1) + + cat := NewAdminCatalog(client) + + _, err := client.ExecuteRequest(catalogHref, http.MethodGet, + "", "error retrieving catalog: %s", nil, cat.AdminCatalog) + + if err != nil { + return nil, err + } + + return cat, nil +} + +// QueryCatalogRecords given a catalog name, retrieves the catalogRecords that match its name +// Returns a list of catalog records for such name, empty list if none was found +func (client *Client) QueryCatalogRecords(name string, ctx TenantContext) ([]*types.CatalogRecord, error) { + util.Logger.Printf("[DEBUG] QueryCatalogRecords") + + var filter string + if name != "" { + filter = fmt.Sprintf("name==%s", url.QueryEscape(name)) + } + + var tenantHeaders map[string]string + + if client.IsSysAdmin && ctx.OrgId != "" && ctx.OrgName != "" { + // Set tenant context headers just for the query + tenantHeaders = map[string]string{ + types.HeaderAuthContext: ctx.OrgName, + types.HeaderTenantContext: ctx.OrgId, + } + } + + queryType := types.QtCatalog + + results, err := client.cumulativeQueryWithHeaders(queryType, nil, map[string]string{ + "type": queryType, + "filter": filter, + "filterEncoded": "true", + }, tenantHeaders) + if err != nil { + return nil, err + } + + catalogs := results.Results.CatalogRecord + + util.Logger.Printf("[DEBUG] QueryCatalogRecords returned with : %#v (%d) and error: %v", catalogs, len(catalogs), err) + return catalogs, nil +} diff --git a/types/v56/types.go b/types/v56/types.go index bb615900b..8e7a6114a 100644 --- a/types/v56/types.go +++ b/types/v56/types.go @@ -3142,6 +3142,7 @@ type CatalogRecord struct { Description string `xml:"description,attr,omitempty"` IsPublished bool `xml:"isPublished,attr,omitempty"` IsShared bool `xml:"isShared,attr,omitempty"` + IsLocal bool `xml:"isLocal,attr,omitempty"` CreationDate string `xml:"creationDate,attr,omitempty"` OrgName string `xml:"orgName,attr,omitempty"` OwnerName string `xml:"ownerName,attr,omitempty"`