Skip to content

Commit

Permalink
Add vcd_tm_storage_class data source vcd_tm_content_library update op…
Browse files Browse the repository at this point in the history
…eration (#1362)

Signed-off-by: abarreiro <[email protected]>
  • Loading branch information
adambarreiro authored Jan 14, 2025
1 parent 71af37b commit 8bc7273
Show file tree
Hide file tree
Showing 18 changed files with 247 additions and 62 deletions.
2 changes: 1 addition & 1 deletion .changes/v4.0.0/1339-features.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
* **New Data Source:** `vcd_tm_region_storage_policy` to read Region Storage Policies [GH-1339, GH-1349]
* **New Data Source:** `vcd_tm_region_storage_policy` to read Region Storage Policies [GH-1339, GH-1349, GH-1362]
* **New Resource:** `vcd_tm_content_library` to manage Content Libraries [GH-1339, GH-1349]
* **New Data Source:** `vcd_tm_content_library` to read Content Libraries [GH-1339, GH-1349]
1 change: 1 addition & 0 deletions .changes/v4.0.0/1362-features.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* **New Data Source:** `vcd_tm_storage_class` to read Storage Classes in Tenant Manager [GH-1362]
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ require (
github.com/hashicorp/go-version v1.6.0
github.com/hashicorp/terraform-plugin-sdk/v2 v2.34.0
github.com/kr/pretty v0.3.1
github.com/vmware/go-vcloud-director/v3 v3.0.0-alpha.13
github.com/vmware/go-vcloud-director/v3 v3.0.0-alpha.14
)

require (
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,8 @@ github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IU
github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok=
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
github.com/vmware/go-vcloud-director/v3 v3.0.0-alpha.13 h1:hX1PukXYr5n4IR61evd+hPW/iv+i5+nzUT8mWyKn034=
github.com/vmware/go-vcloud-director/v3 v3.0.0-alpha.13/go.mod h1:68KHsVns52dsq/w5JQYzauaU/+NAi1FmCxhBrFc/VoQ=
github.com/vmware/go-vcloud-director/v3 v3.0.0-alpha.14 h1:zY0f4JXNsK2z04DuoQ9VLeRw0FZq1sRCRrmSeKog/ps=
github.com/vmware/go-vcloud-director/v3 v3.0.0-alpha.14/go.mod h1:68KHsVns52dsq/w5JQYzauaU/+NAi1FmCxhBrFc/VoQ=
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
Expand Down
12 changes: 6 additions & 6 deletions vcd/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,12 @@ type TestConfig struct {
MaxRetryTimeout int `json:"maxRetryTimeout"`
} `json:"provider"`
Tm struct {
Org string `json:"org"` // temporary field to make skipIfNotTm work
CreateRegion bool `json:"createRegion"`
Region string `json:"region"`
RegionStoragePolicy string `json:"regionStoragePolicy"`
Vdc string `json:"vdc"`
ContentLibrary string `json:"contentLibrary"`
Org string `json:"org"` // temporary field to make skipIfNotTm work
CreateRegion bool `json:"createRegion"`
Region string `json:"region"`
StorageClass string `json:"storageClass"`
Vdc string `json:"vdc"`
ContentLibrary string `json:"contentLibrary"`

CreateNsxtManager bool `json:"createNsxtManager"`
NsxtManagerUsername string `json:"nsxtManagerUsername"`
Expand Down
6 changes: 4 additions & 2 deletions vcd/datasource_vcd_tm_content_library_item.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ func datasourceVcdTmContentLibraryItem() *schema.Resource {
Description: fmt.Sprintf("The ISO-8601 timestamp representing when this %s was last synced if subscribed", labelTmContentLibraryItem),
},
"owner_org_id": {
Type: schema.TypeString,
Type: schema.TypeString,
// TODO: TM: This should be optional: Either Provider or Tenant can create CLs
Computed: true,
Description: fmt.Sprintf("The reference to the organization that the %s belongs to", labelTmContentLibraryItem),
},
Expand All @@ -74,7 +75,8 @@ func datasourceVcdTmContentLibraryItem() *schema.Resource {
func datasourceTmContentLibraryItemRead(_ context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
vcdClient := meta.(*VCDClient)

cl, err := vcdClient.GetContentLibraryById(d.Get("content_library_id").(string))
// TODO: TM: Tenant Context should not be nil and depend on the configured owner_org_id
cl, err := vcdClient.GetContentLibraryById(d.Get("content_library_id").(string), nil)
if err != nil {
return diag.Errorf("error retrieving Content Library: %s", err)
}
Expand Down
94 changes: 94 additions & 0 deletions vcd/datasource_vcd_tm_storage_class.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package vcd

import (
"context"
"fmt"
"github.com/vmware/go-vcloud-director/v3/types/v56"

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

const labelTmStorageClass = "Storage Class"

func datasourceVcdTmStorageClass() *schema.Resource {
return &schema.Resource{
ReadContext: datasourceVcdTmStorageClassRead,
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
Description: fmt.Sprintf("%s name", labelTmStorageClass),
},
"region_id": {
Type: schema.TypeString,
Required: true,
Description: fmt.Sprintf("The Region that this %s belongs to", labelTmStorageClass),
},
"storage_capacity_mib": {
Type: schema.TypeInt,
Computed: true,
Description: fmt.Sprintf("The total storage capacity of the %s in mebibytes", labelTmStorageClass),
},
"storage_consumed_mib": {
Type: schema.TypeInt,
Computed: true,
Description: fmt.Sprintf("For tenants, this represents the total storage given to all namespaces consuming from this %s in mebibytes. "+
"For providers, this represents the total storage given to tenants from this %s in mebibytes.", labelTmStorageClass, labelTmStorageClass),
},
"zone_ids": {
Type: schema.TypeSet,
Computed: true,
Description: fmt.Sprintf("A set with all the IDs of the zones available to the %s", labelTmStorageClass),
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
},
}
}

func datasourceVcdTmStorageClassRead(_ context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
vcdClient := meta.(*VCDClient)
regionId := d.Get("region_id").(string)
region, err := vcdClient.GetRegionById(regionId)
if err != nil {
return diag.Errorf("error retrieving Region with ID '%s': %s", regionId, err)
}

scName := d.Get("name").(string)
sc, err := region.GetStorageClassByName(scName)
if err != nil {
return diag.Errorf("error retrieving Storage Class '%s': %s", scName, err)
}

err = setStorageClassData(d, sc.StorageClass)
if err != nil {
return diag.Errorf("error saving Storage Class data into state: %s", err)
}

d.SetId(sc.StorageClass.ID)
return nil
}

func setStorageClassData(d *schema.ResourceData, sc *types.StorageClass) error {
dSet(d, "name", sc.Name)
dSet(d, "storage_capacity_mib", sc.StorageCapacityMiB)
dSet(d, "storage_consumed_mib", sc.StorageConsumedMiB)
regionId := ""
if sc.Region != nil {
regionId = sc.Region.ID
}
dSet(d, "region_id", regionId)

var zoneIds []string
if len(sc.Zones) > 0 {
zoneIds = extractIdsFromOpenApiReferences(sc.Zones)
}
err := d.Set("zone_ids", zoneIds)
if err != nil {
return err
}

return nil
}
1 change: 1 addition & 0 deletions vcd/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ var globalDataSourceMap = map[string]*schema.Resource{
"vcd_nsxt_alb_virtual_service_http_sec_rules": datasourceVcdAlbVirtualServiceSecRules(), // 3.14
"vcd_tm_org": datasourceVcdTmOrg(), // 4.0
"vcd_tm_region_storage_policy": datasourceVcdTmRegionStoragePolicy(), // 4.0
"vcd_tm_storage_class": datasourceVcdTmStorageClass(), // 4.0
"vcd_tm_content_library": datasourceVcdTmContentLibrary(), // 4.0
"vcd_tm_supervisor": datasourceVcdTmSupervisor(), // 4.0
"vcd_tm_supervisor_zone": datasourceVcdTmSupervisorZone(), // 4.0
Expand Down
35 changes: 17 additions & 18 deletions vcd/resource_vcd_tm_content_library.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ package vcd
import (
"context"
"fmt"
"strings"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/vmware/go-vcloud-director/v3/govcd"
Expand All @@ -24,13 +22,11 @@ func resourceVcdTmContentLibrary() *schema.Resource {
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true, // TODO: TM: Update not supported
Description: "The name of the Content Library",
},
"storage_class_ids": {
Type: schema.TypeSet,
Required: true,
ForceNew: true, // TODO: TM: Update not supported
Description: "A set of storage class IDs used by this Content Library",
Elem: &schema.Schema{
Type: schema.TypeString,
Expand All @@ -56,7 +52,6 @@ func resourceVcdTmContentLibrary() *schema.Resource {
"description": {
Type: schema.TypeString,
Optional: true,
ForceNew: true, // TODO: TM: Update not supported
Description: "The description of the Content Library",
},
"is_shared": {
Expand All @@ -76,34 +71,33 @@ func resourceVcdTmContentLibrary() *schema.Resource {
"provider) or TENANT (Content Library that is scoped to a tenant organization)",
},
"owner_org_id": {
Type: schema.TypeString,
Type: schema.TypeString,
// TODO: TM: This should be optional: Either Provider or Tenant can create CLs
Computed: true,
Description: "The reference to the Organization that the Content Library belongs to",
},
"subscription_config": {
Type: schema.TypeList,
MaxItems: 1,
Optional: true,
ForceNew: true, // Can't change subscription settings
Description: "A block representing subscription settings of a Content Library",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"subscription_url": {
Type: schema.TypeString,
Required: true,
ForceNew: true, // TODO: TM: Update not supported
Description: "Subscription url of this Content Library",
},
"password": {
Type: schema.TypeString,
Optional: true, // Required at Runtime as cannot be Required + Computed in schema. (It is computed as password cannot be recovered)
Computed: true,
ForceNew: true, // TODO: TM: Update not supported
Description: "Password to use to authenticate with the publisher",
},
"need_local_copy": {
Type: schema.TypeBool,
Optional: true,
ForceNew: true, // TODO: TM: Update not supported
Description: "Whether to eagerly download content from publisher and store it locally",
},
},
Expand All @@ -126,7 +120,8 @@ func resourceVcdTmContentLibraryCreate(ctx context.Context, d *schema.ResourceDa
return diag.Errorf("error getting Content Library type: %s", err)
}

cl, err := vcdClient.CreateContentLibrary(t)
// TODO: TM: Tenant Context should not be nil and depend on the configured owner_org_id
cl, err := vcdClient.CreateContentLibrary(t, nil)
if err != nil {
return diag.Errorf("error creating Content Library: %s", err)
}
Expand All @@ -138,7 +133,8 @@ func resourceVcdTmContentLibraryCreate(ctx context.Context, d *schema.ResourceDa

func resourceVcdTmContentLibraryUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
vcdClient := meta.(*VCDClient)
rsp, err := vcdClient.GetContentLibraryById(d.Id())
// TODO: TM: Tenant Context should not be nil and depend on the configured owner_org_id
rsp, err := vcdClient.GetContentLibraryById(d.Id(), nil)
if err != nil {
return diag.Errorf("error retrieving Content Library: %s", err)
}
Expand All @@ -164,10 +160,11 @@ func genericVcdTmContentLibraryRead(_ context.Context, d *schema.ResourceData, m

var cl *govcd.ContentLibrary
var err error
// TODO: TM: Tenant Context should not be nil and depend on the configured owner_org_id
if d.Id() != "" {
cl, err = vcdClient.GetContentLibraryById(d.Id())
cl, err = vcdClient.GetContentLibraryById(d.Id(), nil)
} else {
cl, err = vcdClient.GetContentLibraryByName(d.Get("name").(string))
cl, err = vcdClient.GetContentLibraryByName(d.Get("name").(string), nil)
}
if err != nil {
if origin == "resource" && govcd.ContainsNotFound(err) {
Expand All @@ -188,12 +185,14 @@ func genericVcdTmContentLibraryRead(_ context.Context, d *schema.ResourceData, m

func resourceVcdTmContentLibraryDelete(_ context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
vcdClient := meta.(*VCDClient)
cl, err := vcdClient.GetContentLibraryById(d.Id())
// TODO: TM: Tenant Context should not be nil and depend on the configured owner_org_id
cl, err := vcdClient.GetContentLibraryById(d.Id(), nil)
if err != nil {
return diag.Errorf("error retrieving Content Library: %s", err)
}

err = cl.Delete()
// TODO: TM: Add two new arguments "force_delete" and "delete_recursive"
err = cl.Delete(true, true)
if err != nil {
return diag.Errorf("error deleting Content Library: %s", err)
}
Expand All @@ -203,7 +202,8 @@ func resourceVcdTmContentLibraryDelete(_ context.Context, d *schema.ResourceData

func resourceVcdTmContentLibraryImport(_ context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
vcdClient := meta.(*VCDClient)
rsp, err := vcdClient.GetContentLibraryByName(d.Id())
// TODO: TM: Tenant Context should not be nil and depend on the configured owner_org_id
rsp, err := vcdClient.GetContentLibraryByName(d.Id(), nil)
if err != nil {
return nil, fmt.Errorf("error retrieving Content Library with name '%s': %s", d.Id(), err)
}
Expand Down Expand Up @@ -246,8 +246,7 @@ func setTmContentLibraryData(d *schema.ResourceData, cl *types.ContentLibrary) e

scs := make([]string, len(cl.StorageClasses))
for i, sc := range cl.StorageClasses {
// TODO: TM: When vcd_region_storage_policy data source starts using :storageClass: UUID, we can get rid of this
scs[i] = strings.ReplaceAll(sc.ID, "storageClass", "regionStoragePolicy")
scs[i] = sc.ID
}
err := d.Set("storage_class_ids", scs)
if err != nil {
Expand Down
12 changes: 8 additions & 4 deletions vcd/resource_vcd_tm_content_library_item.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@ func resourceVcdTmContentLibraryItemCreate(ctx context.Context, d *schema.Resour
vcdClient := meta.(*VCDClient)

clId := d.Get("content_library_id").(string)
cl, err := vcdClient.GetContentLibraryById(clId)
// TODO: TM: Tenant Context should not be nil and depend on the configured owner_org_id
cl, err := vcdClient.GetContentLibraryById(clId, nil)
if err != nil {
return diag.Errorf("could not retrieve Content Library with ID '%s': %s", clId, err)
}
Expand Down Expand Up @@ -152,7 +153,8 @@ func resourceVcdTmContentLibraryItemRead(ctx context.Context, d *schema.Resource
vcdClient := meta.(*VCDClient)

clId := d.Get("content_library_id").(string)
cl, err := vcdClient.GetContentLibraryById(clId)
// TODO: TM: Tenant Context should not be nil and depend on the configured owner_org_id
cl, err := vcdClient.GetContentLibraryById(clId, nil)
if err != nil {
return diag.Errorf("could not retrieve Content Library with ID '%s': %s", clId, err)
}
Expand All @@ -169,7 +171,8 @@ func resourceVcdTmContentLibraryItemDelete(ctx context.Context, d *schema.Resour
vcdClient := meta.(*VCDClient)

clId := d.Get("content_library_id").(string)
cl, err := vcdClient.GetContentLibraryById(clId)
// TODO: TM: Tenant Context should not be nil and depend on the configured owner_org_id
cl, err := vcdClient.GetContentLibraryById(clId, nil)
if err != nil {
return diag.Errorf("could not retrieve Content Library with ID '%s': %s", clId, err)
}
Expand All @@ -190,7 +193,8 @@ func resourceVcdTmContentLibraryItemImport(_ context.Context, d *schema.Resource
return nil, fmt.Errorf("ID syntax should be \"Content Library name\".\"Content Library Item name\", where '.' is a customisable import separator")
}

cl, err := vcdClient.GetContentLibraryByName(id[0])
// TODO: TM: Tenant Context should not be nil and depend on the configured owner_org_id
cl, err := vcdClient.GetContentLibraryByName(id[0], nil)
if err != nil {
return nil, fmt.Errorf("error getting Content Library with name '%s' for import: %s", id[0], err)
}
Expand Down
4 changes: 2 additions & 2 deletions vcd/resource_vcd_tm_content_library_item_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func TestAccVcdTmContentLibraryItem(t *testing.T) {
contentLibraryHcl, contentLibraryHclRef := getContentLibraryHcl(t, regionHclRef)

var params = StringMap{
"Name": t.Name() + "6",
"Name": t.Name(),
"ContentLibraryRef": fmt.Sprintf("%s.id", contentLibraryHclRef),
"OvaPath": "../test-resources/test_vapp_template.ova",
"Tags": "tm",
Expand Down Expand Up @@ -58,7 +58,7 @@ func TestAccVcdTmContentLibraryItem(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "is_published", "false"),
resource.TestCheckResourceAttrSet(resourceName, "image_identifier"),
resource.TestMatchResourceAttr(resourceName, "owner_org_id", regexp.MustCompile("urn:vcloud:org:")),
resource.TestCheckResourceAttr(resourceName, "status", ""),
resource.TestCheckResourceAttr(resourceName, "status", "READY"),
resource.TestCheckResourceAttr(resourceName, "last_successful_sync", ""),
resource.TestCheckResourceAttr(resourceName, "version", "1"),
),
Expand Down
Loading

0 comments on commit 8bc7273

Please sign in to comment.