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

Fix issue 944 - allow org users to read shared catalogs #949

Merged
merged 16 commits into from
Dec 5, 2022
1 change: 1 addition & 0 deletions .changes/v3.8.1/949-bug-fixes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* Fix issue #944 shared catalog datasource not working [GH-949]
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 3.8.1 (TBC)

Changes in progress for v3.8.1 are available at [.changes/v3.8.1](https://github.com/vmware/terraform-provider-vcd/tree/main/.changes/v3.8.1) until the release.

## 3.8.0 (November 25, 2022)

### FEATURES
Expand Down
2 changes: 1 addition & 1 deletion PREVIOUS_VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v3.7.0
v3.8.0
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v3.8.0
v3.8.1
4 changes: 4 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,7 @@ require (
google.golang.org/grpc v1.50.1 // indirect
google.golang.org/protobuf v1.28.1 // indirect
)

replace github.com/vmware/go-vcloud-director/v2 => github.com/dataclouder/go-vcloud-director/v2 v2.17.0-alpha.3.0.20221202070623-3d1e5ac6ea20

//replace github.com/vmware/go-vcloud-director/v2 => ../go-vcloud-director
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkY
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/dataclouder/go-vcloud-director/v2 v2.17.0-alpha.3.0.20221202070623-3d1e5ac6ea20 h1:9q8DQBPyXQkgWEjuLBMP/rbovqhHuV1mrMcKVbLHODI=
github.com/dataclouder/go-vcloud-director/v2 v2.17.0-alpha.3.0.20221202070623-3d1e5ac6ea20/go.mod h1:KjnB8t5l1bRrc+jLKDJbx0vZLRzz2RPzNQ7xzg7yI3o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand Down Expand Up @@ -178,8 +180,6 @@ github.com/vmihailenco/msgpack/v4 v4.3.12 h1:07s4sz9IReOgdikxLTKNbBdqDMLsjPKXwvC
github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4=
github.com/vmihailenco/tagparser v0.1.1 h1:quXMXlA39OCbd2wAdTsGDlK9RkOk6Wuw+x37wVyIuWY=
github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI=
github.com/vmware/go-vcloud-director/v2 v2.17.0 h1:msrrtEKD7H/e3cNPaXlCkZf3TMzSSyH306EXettv0c8=
github.com/vmware/go-vcloud-director/v2 v2.17.0/go.mod h1:KjnB8t5l1bRrc+jLKDJbx0vZLRzz2RPzNQ7xzg7yI3o=
github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI=
github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0=
github.com/zclconf/go-cty v1.1.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s=
Expand Down
84 changes: 74 additions & 10 deletions vcd/datasource_vcd_catalog.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package vcd

import (
"context"
"log"
"fmt"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/vmware/go-vcloud-director/v2/types/v56"
"github.com/vmware/go-vcloud-director/v2/util"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/vmware/go-vcloud-director/v2/govcd"
Expand Down Expand Up @@ -106,6 +108,11 @@ func datasourceVcdCatalog() *schema.Resource {
Computed: true,
Description: "True if this catalog is shared.",
},
"is_local": {
Type: schema.TypeBool,
Computed: true,
Description: "True if this catalog belongs to the current organization.",
},
"is_published": {
Type: schema.TypeBool,
Computed: true,
Expand Down Expand Up @@ -141,34 +148,87 @@ func datasourceVcdCatalog() *schema.Resource {
}
}

func getCatalogFromResource(catalogName string, d *schema.ResourceData, meta interface{}) (*govcd.AdminCatalog, error) {
vcdClient := meta.(*VCDClient)

orgName, err := vcdClient.GetOrgNameFromResource(d)
if err != nil {
return nil, fmt.Errorf("'org' property not supplied in the resource or in provider: %s", err)
}

tenantContext := govcd.TenantContext{}
if vcdClient.Client.IsSysAdmin {
org, err := vcdClient.GetAdminOrgByName(orgName)
if err != nil {
return nil, fmt.Errorf("[getCatalogFromResource] error retrieving org %s: %s", orgName, err)
}
tenantContext.OrgId = org.AdminOrg.ID
tenantContext.OrgName = orgName
}
catalogRecords, err := vcdClient.VCDClient.Client.QueryCatalogRecords(catalogName, tenantContext)
if err != nil {
return nil, fmt.Errorf("[getCatalogFromResource] error retrieving catalog records for catalog %s: %s", catalogName, err)
}
var catalogRecord *types.CatalogRecord
var orgNames []string
for _, cr := range catalogRecords {
orgNames = append(orgNames, cr.OrgName)
if cr.OrgName == orgName {
catalogRecord = cr
break
}
}
if catalogRecord == nil {
message := fmt.Sprintf("no records found for catalog '%s' from org '%s'", catalogName, orgName)
if len(orgNames) > 0 {
message = fmt.Sprintf("%s\nThere are catalogs with the same name from other orgs: %v", message, orgNames)
}
return nil, fmt.Errorf(message)
}
return vcdClient.VCDClient.Client.GetCatalogByHref(catalogRecord.HREF)
}

func datasourceVcdCatalogRead(_ context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
var (
vcdClient = meta.(*VCDClient)
catalog *govcd.AdminCatalog
vcdClient = meta.(*VCDClient)
catalog *govcd.AdminCatalog
err error
catalogOrgIsAvailable bool = true
)

if !nameOrFilterIsSet(d) {
return diag.Errorf(noNameOrFilterError, "vcd_catalog")
}

adminOrg, err := vcdClient.GetAdminOrgFromResource(d)
orgName, err := vcdClient.GetOrgNameFromResource(d)
if err != nil {
return diag.Errorf(errorRetrievingOrg, err)
return diag.Errorf("'org' property not supplied in the resource or in provider: %s", err)
}

adminOrg, orgErr := vcdClient.GetAdminOrgFromResource(d)
orgFound := ""
if orgErr != nil {
util.Logger.Printf("[TRACE] error retrieving org: %s", orgErr)
catalogOrgIsAvailable = false
orgFound = "NOT"
}
log.Printf("[TRACE] Org %s found", adminOrg.AdminOrg.Name)
util.Logger.Printf("[TRACE] Org '%s' %s found", orgName, orgFound)

identifier := d.Get("name").(string)

filter, hasFilter := d.GetOk("filter")

if hasFilter {
if !catalogOrgIsAvailable {
return diag.Errorf("cannot search by filter when org is not reachable by the current user. "+
"If the catalog is shared, it will be retrieved only by name: %s", orgErr)
}
catalog, err = getCatalogByFilter(adminOrg, filter, vcdClient.Client.IsSysAdmin)
} else {
catalog, err = adminOrg.GetAdminCatalogByNameOrId(identifier, false)
catalog, err = getCatalogFromResource(identifier, d, meta)
}
if err != nil {
log.Printf("[DEBUG] Catalog %s not found. Setting ID to nothing", identifier)
return diag.Errorf("error retrieving catalog %s: %s", identifier, err)
return diag.Errorf("[catalog read DS] error retrieving catalog %s: %s - %s", identifier, govcd.ErrorEntityNotFound, err)
}

dSet(d, "description", catalog.AdminCatalog.Description)
Expand All @@ -193,7 +253,11 @@ func datasourceVcdCatalogRead(_ context.Context, d *schema.ResourceData, meta in
return diag.Errorf("There was an issue when setting metadata into the schema - %s", err)
}

err = setCatalogData(d, adminOrg, catalog, "vcd_catalog")
orgId := ""
if adminOrg != nil {
orgId = adminOrg.AdminOrg.ID
}
err = setCatalogData(d, vcdClient, orgName, orgId, catalog, "vcd_catalog")
if err != nil {
return diag.FromErr(err)
}
Expand Down
7 changes: 6 additions & 1 deletion vcd/datasource_vcd_subscribed_catalog.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@ func datasourceVcdSubscribedCatalog() *schema.Resource {
Computed: true,
Description: "True if this catalog is shared.",
},
"is_local": {
Type: schema.TypeBool,
Computed: true,
Description: "True if this catalog belongs to the current organization.",
},
"is_published": {
Type: schema.TypeBool,
Computed: true,
Expand Down Expand Up @@ -180,7 +185,7 @@ func datasourceVcdSubscribedCatalogRead(ctx context.Context, d *schema.ResourceD

dSet(d, "subscription_url", adminCatalog.AdminCatalog.ExternalCatalogSubscription.Location)
dSet(d, "make_local_copy", adminCatalog.AdminCatalog.ExternalCatalogSubscription.LocalCopy)
err = setCatalogData(d, adminOrg, adminCatalog, "vcd_subscribed_catalog")
err = setCatalogData(d, vcdClient, adminOrg.AdminOrg.Name, adminOrg.AdminOrg.ID, adminCatalog, "vcd_subscribed_catalog")
if err != nil {
return diag.Errorf("%v", err)
}
Expand Down
40 changes: 30 additions & 10 deletions vcd/resource_vcd_catalog.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ import (
"sort"
"strings"

"github.com/kr/pretty"
"github.com/vmware/go-vcloud-director/v2/types/v56"
"github.com/vmware/go-vcloud-director/v2/util"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"

Expand Down Expand Up @@ -142,6 +144,11 @@ func resourceVcdCatalog() *schema.Resource {
Computed: true,
Description: "True if this catalog is shared.",
},
"is_local": {
Type: schema.TypeBool,
Computed: true,
Description: "True if this catalog belongs to the current organization.",
},
"is_published": {
Type: schema.TypeBool,
Computed: true,
Expand Down Expand Up @@ -289,7 +296,7 @@ func genericResourceVcdCatalogRead(d *schema.ResourceData, meta interface{}) err
return err
}

err = setCatalogData(d, adminOrg, adminCatalog, "vcd_catalog")
err = setCatalogData(d, vcdClient, adminOrg.AdminOrg.Name, adminOrg.AdminOrg.ID, adminCatalog, "vcd_catalog")
if err != nil {
return err
}
Expand Down Expand Up @@ -462,19 +469,32 @@ func resourceVcdCatalogImport(_ context.Context, d *schema.ResourceData, meta in
return []*schema.ResourceData{d}, nil
}

func setCatalogData(d *schema.ResourceData, adminOrg *govcd.AdminOrg, adminCatalog *govcd.AdminCatalog, resourceType string) error {
func setCatalogData(d *schema.ResourceData, vcdClient *VCDClient, orgName, orgId string, adminCatalog *govcd.AdminCatalog, resourceType string) error {
// Catalog record is retrieved to get the owner name, number of vApp templates and medias, and if the catalog is shared and published
catalogRecords, err := adminOrg.FindCatalogRecords(adminCatalog.AdminCatalog.Name)
catalogRecords, err := vcdClient.VCDClient.Client.QueryCatalogRecords(adminCatalog.AdminCatalog.Name, govcd.TenantContext{OrgName: orgName, OrgId: orgId})
if err != nil {
log.Printf("[DEBUG] Unable to retrieve catalog record: %s", err)
return fmt.Errorf("unable to retrieve catalog record - %s", err)
log.Printf("[DEBUG] [setCatalogData] Unable to retrieve catalog records: %s", err)
return fmt.Errorf("[setCatalogData] unable to retrieve catalog records - %s", err)
}
var catalogRecord *types.CatalogRecord

for _, cr := range catalogRecords {
if cr.OrgName == orgName {
catalogRecord = cr
break
}
}
if catalogRecord == nil {
return fmt.Errorf("[setCatalogData] error retrieving catalog record for catalog '%s' from org '%s'", adminCatalog.AdminCatalog.Name, orgName)
}

dSet(d, "catalog_version", catalogRecords[0].Version)
dSet(d, "owner_name", catalogRecords[0].OwnerName)
dSet(d, "is_published", catalogRecords[0].IsPublished)
dSet(d, "is_shared", catalogRecords[0].IsShared)
dSet(d, "publish_subscription_type", catalogRecords[0].PublishSubscriptionType)
util.Logger.Printf("[setCatalogData] catalogRecord %# v\n", pretty.Formatter(catalogRecord))
dSet(d, "catalog_version", catalogRecord.Version)
dSet(d, "owner_name", catalogRecord.OwnerName)
dSet(d, "is_published", catalogRecord.IsPublished)
dSet(d, "is_shared", catalogRecord.IsShared)
dSet(d, "is_local", catalogRecord.IsLocal)
dSet(d, "publish_subscription_type", catalogRecord.PublishSubscriptionType)

var rawMediaItemsList []interface{}
var rawVappTemplatesList []interface{}
Expand Down
7 changes: 6 additions & 1 deletion vcd/resource_vcd_subscribed_catalog.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,11 @@ func resourceVcdSubscribedCatalog() *schema.Resource {
Computed: true,
Description: "True if this catalog is shared.",
},
"is_local": {
Type: schema.TypeBool,
Computed: true,
Description: "True if this catalog belongs to the current organization.",
},
"is_published": {
Type: schema.TypeBool,
Computed: true,
Expand Down Expand Up @@ -335,7 +340,7 @@ func resourceVcdSubscribedCatalogRead(ctx context.Context, d *schema.ResourceDat
}
dSet(d, "subscription_url", adminCatalog.AdminCatalog.ExternalCatalogSubscription.Location)
dSet(d, "make_local_copy", adminCatalog.AdminCatalog.ExternalCatalogSubscription.LocalCopy)
err = setCatalogData(d, adminOrg, adminCatalog, "vcd_subscribed_catalog")
err = setCatalogData(d, vcdClient, adminOrg.AdminOrg.Name, adminOrg.AdminOrg.ID, adminCatalog, "vcd_subscribed_catalog")
if err != nil {
return diag.Errorf("%v", err)
}
Expand Down
1 change: 1 addition & 0 deletions website/docs/d/catalog.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ The following arguments are supported:
* `media_item_list` - (*v3.8+*) List of media item names in this catalog, in alphabetical order.
* `is_shared` - (*v3.6+*) Indicates if the catalog is shared.
* `is_published` - (*v3.6+*) Indicates if this catalog is shared to all organizations.
* `is_local` - (*v3.8.1+*) Indicates if this catalog was created in the current organization.
* `created` - (*v3.6+*) Date and time of catalog creation
* `publish_subscription_type` - (*v3.6+*) Shows if the catalog is `PUBLISHED`, if it is a subscription from another one (`SUBSCRIBED`), or none of those (`UNPUBLISHED`).
* `publish_subscription_url` - (*v3.8+*) URL to which other catalogs can subscribe.
Expand Down
1 change: 1 addition & 0 deletions website/docs/d/subscribed_catalog.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ The following arguments are supported:
* `media_item_list` List of media item names in this catalog, in alphabetical order.
* `is_shared` - Indicates if the catalog is shared (`true` or `false`).
* `is_published` - Indicates if this catalog is available for subscription. (Always return `false` for this data source)
* `is_local` - (*v3.8.1+*) Indicates if this catalog was created in the current organization.
* `publish_subscription_type` - Shows if the catalog is published, if it is a subscription from another one or none of those. (Always returns `SUBSCRIBED` for this data source)
* `href` - the catalog's Hyper reference.
* `created` - Date and time of catalog creation.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
layout: "vcd"
page_title: "VMware Cloud Director: catalog-subscription-and-sharing"
page_title: "VMware Cloud Director: Catalog subscription and sharing"
sidebar_current: "docs-vcd-guides-catalog-subscription-and-sharing"
description: |-
Provides guidance to VMware Cloud catalog publishing, subscribing, and sharing
Expand Down
2 changes: 1 addition & 1 deletion website/docs/index.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ description: |-
The VMware Cloud Director provider is used to interact with the resources supported by VMware Cloud Director. The provider needs to be configured with the proper credentials before it can be used.
---

# VMware Cloud Director Provider 3.8
# VMware Cloud Director Provider 3.8.1

The VMware Cloud Director provider is used to interact with the resources supported by VMware Cloud Director. The provider needs to be configured with the proper credentials before it can be used.

Expand Down
5 changes: 4 additions & 1 deletion website/docs/r/catalog.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ resource "vcd_catalog" "myNewCatalog" {

The following arguments are supported:

* `org` - (Optional) The name of organization to use, optional if defined at provider level. Useful when connected as sysadmin working across different organisations
* `org` - (Optional) The name of organization to use, optional if defined at provider level. Useful when connected as sysadmin working across different organizations.
When using a catalog shared from another organization, this field must have the name of that one, not the current one.
If you don't know the name of the sharing org, and put the current one, an error message will list the possible names.
* `name` - (Required) Catalog name
* `description` - (Optional) Description of catalog
* `storage_profile_id` - (Optional, *v3.1+*) Allows to set specific storage profile to be used for catalog. **Note.** Data
Expand All @@ -75,6 +77,7 @@ source [vcd_storage_profile](/providers/vmware/vcd/latest/docs/data-sources/stor
* `number_of_media` - (*v3.6+*) Number of media items available in this catalog.
* `is_shared` - (*v3.6+*) Indicates if the catalog is shared.
* `is_published` - (*v3.6+*) Indicates if this catalog is shared to all organizations.
* `is_local` - (*v3.8.1+*) Indicates if this catalog was created in the current organization.
* `created` - (*v3.6+*) Date and time of catalog creation
* `publish_subscription_type` - (*v3.6+*) Shows if the catalog is `PUBLISHED`, if it is a subscription from another one (`SUBSCRIBED`), or none of those (`UNPUBLISHED`).
* `publish_subscription_url` - (*v3.8+*) URL to which other catalogs can subscribe.
Expand Down
1 change: 1 addition & 0 deletions website/docs/r/subscribed_catalog.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ The following arguments are supported:
* `media_item_list` List of media item names in this catalog, in alphabetical order.
* `is_shared` - Indicates if the catalog is shared.
* `is_published` - Indicates if this catalog is available for subscription. (Always false)
* `is_local` - (*v3.8.1+*) Indicates if this catalog was created in the current organization.
* `publish_subscription_type` - Shows if the catalog is published, if it is a subscription from another one or none of those. (Always `SUBSCRIBED`)
* `href` - the catalog's Hyper reference.
* `created` - Date and time of catalog creation. This is the creation date of the subscription, not the original published catalog.
Expand Down