Skip to content

Commit

Permalink
Add custom attribute support to VMFS Datastore resource
Browse files Browse the repository at this point in the history
  • Loading branch information
rmbrad committed Dec 18, 2017
1 parent e911d85 commit 3e2ba87
Show file tree
Hide file tree
Showing 4 changed files with 195 additions and 0 deletions.
10 changes: 10 additions & 0 deletions vsphere/helper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,16 @@ func testGetDatastore(s *terraform.State, resAddr string) (*object.Datastore, er
return datastore.FromID(vars.client, vars.resourceID)
}

// testGetDatastoreProperties is a convenience method that adds an extra step
// to testGetDatastore to get the properties of a datastore.
func testGetDatastoreProperties(s *terraform.State, resourceName string) (*mo.Datastore, error) {
ds, err := testGetDatastore(s, "vsphere_vmfs_datastore."+resourceName)
if err != nil {
return nil, err
}
return datastore.Properties(ds)
}

// testAccResourceVSphereDatastoreCheckTags is a check to ensure that the
// supplied datastore has had the tags that have been created with the supplied
// tag resource name attached.
Expand Down
32 changes: 32 additions & 0 deletions vsphere/resource_vsphere_vmfs_datastore.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
"github.com/terraform-providers/terraform-provider-vsphere/vsphere/internal/helper/customattribute"
"github.com/terraform-providers/terraform-provider-vsphere/vsphere/internal/helper/datastore"
"github.com/terraform-providers/terraform-provider-vsphere/vsphere/internal/helper/folder"
"github.com/terraform-providers/terraform-provider-vsphere/vsphere/internal/helper/structure"
Expand Down Expand Up @@ -90,6 +91,8 @@ func resourceVSphereVmfsDatastore() *schema.Resource {

// Add tags schema
s[vSphereTagAttributeKey] = tagsSchema()
// Add custom attributes schema
s[customattribute.ConfigKey] = customattribute.ConfigSchema()

return &schema.Resource{
Create: resourceVSphereVmfsDatastoreCreate,
Expand All @@ -113,6 +116,11 @@ func resourceVSphereVmfsDatastoreCreate(d *schema.ResourceData, meta interface{}
if err != nil {
return err
}
// Verify a proper vCenter before proceeding if custom attributes are defined
attrsProcessor, err := customattribute.GetDiffProcessorIfAttributesDefined(client, d)
if err != nil {
return err
}

hsID := d.Get("host_system_id").(string)
dss, err := hostDatastoreSystemFromHostSystemID(client, hsID)
Expand Down Expand Up @@ -158,6 +166,13 @@ func resourceVSphereVmfsDatastoreCreate(d *schema.ResourceData, meta interface{}
}
}

// Set custom attributes
if attrsProcessor != nil {
if err := attrsProcessor.ProcessDiff(ds); err != nil {
return err
}
}

// Now add any remaining disks.
for _, disk := range disks[1:] {
spec, err := diskSpecForExtend(dss, ds, disk.(string))
Expand Down Expand Up @@ -228,6 +243,11 @@ func resourceVSphereVmfsDatastoreRead(d *schema.ResourceData, meta interface{})
}
}

// Read custom attributes
if customattribute.IsSupported(client) {
customattribute.ReadFromResource(client, props.Entity(), d)
}

return nil
}

Expand All @@ -240,6 +260,11 @@ func resourceVSphereVmfsDatastoreUpdate(d *schema.ResourceData, meta interface{}
if err != nil {
return err
}
// Verify a proper vCenter before proceeding if custom attributes are defined
attrsProcessor, err := customattribute.GetDiffProcessorIfAttributesDefined(client, d)
if err != nil {
return err
}

hsID := d.Get("host_system_id").(string)
dss, err := hostDatastoreSystemFromHostSystemID(client, hsID)
Expand Down Expand Up @@ -275,6 +300,13 @@ func resourceVSphereVmfsDatastoreUpdate(d *schema.ResourceData, meta interface{}
}
}

// Apply custom attribute updates
if attrsProcessor != nil {
if err := attrsProcessor.ProcessDiff(ds); err != nil {
return err
}
}

// Veto this update if it means a disk was removed. Shrinking
// datastores/removing extents is not supported.
old, new := d.GetChange("disks")
Expand Down
143 changes: 143 additions & 0 deletions vsphere/resource_vsphere_vmfs_datastore_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,53 @@ func TestAccResourceVSphereVmfsDatastore(t *testing.T) {
},
},
},
{
"single custom attribute",
resource.TestCase{
PreCheck: func() {
testAccPreCheck(tp)
testAccResourceVSphereVmfsDatastorePreCheck(tp)
},
Providers: testAccProviders,
CheckDestroy: testAccResourceVSphereVmfsDatastoreExists(false),
Steps: []resource.TestStep{
{
Config: testAccResourceVSphereVmfsDatastoreConfigCustomAttributes(),
Check: resource.ComposeTestCheckFunc(
testAccResourceVSphereVmfsDatastoreExists(true),
testAccResourceVSphereVmfsDatastoreHasCustomAttributes(),
),
},
},
},
},
{
"multi custom attribute",
resource.TestCase{
PreCheck: func() {
testAccPreCheck(tp)
testAccResourceVSphereVmfsDatastorePreCheck(tp)
},
Providers: testAccProviders,
CheckDestroy: testAccResourceVSphereVmfsDatastoreExists(false),
Steps: []resource.TestStep{
{
Config: testAccResourceVSphereVmfsDatastoreConfigCustomAttributes(),
Check: resource.ComposeTestCheckFunc(
testAccResourceVSphereVmfsDatastoreExists(true),
testAccResourceVSphereVmfsDatastoreHasCustomAttributes(),
),
},
{
Config: testAccResourceVSphereVmfsDatastoreConfigMultiCustomAttributes(),
Check: resource.ComposeTestCheckFunc(
testAccResourceVSphereVmfsDatastoreExists(true),
testAccResourceVSphereVmfsDatastoreHasCustomAttributes(),
),
},
},
},
},
}

for _, tc := range testAccResourceVSphereVmfsDatastoreCases {
Expand Down Expand Up @@ -390,6 +437,16 @@ func testAccResourceVSphereVmfsDatastoreMatchInventoryPath(expected string) reso
}
}

func testAccResourceVSphereVmfsDatastoreHasCustomAttributes() resource.TestCheckFunc {
return func(s *terraform.State) error {
props, err := testGetDatastoreProperties(s, "datastore")
if err != nil {
return err
}
return testResourceHasCustomAttributeValues(s, "vsphere_vmfs_datastore", "datastore", props.Entity())
}
}

func testAccResourceVSphereVmfsDatastoreConfigStaticSingle() string {
return fmt.Sprintf(`
variable "disk0" {
Expand Down Expand Up @@ -713,3 +770,89 @@ resource "vsphere_vmfs_datastore" "datastore" {
}
`, os.Getenv("VSPHERE_DS_VMFS_DISK0"), os.Getenv("VSPHERE_DS_VMFS_DISK1"), os.Getenv("VSPHERE_DATACENTER"), os.Getenv("VSPHERE_ESXI_HOST"))
}

func testAccResourceVSphereVmfsDatastoreConfigCustomAttributes() string {
return fmt.Sprintf(`
variable "disk0" {
type = "string"
default = "%s"
}
data "vsphere_datacenter" "datacenter" {
name = "%s"
}
data "vsphere_host" "esxi_host" {
name = "%s"
datacenter_id = "${data.vsphere_datacenter.datacenter.id}"
}
resource "vsphere_custom_attribute" "terraform-test-attribute" {
name = "terraform-test-attribute"
managed_object_type = "Datastore"
}
locals {
vmfs_attrs = {
"${vsphere_custom_attribute.terraform-test-attribute.id}" = "value"
}
}
resource "vsphere_vmfs_datastore" "datastore" {
name = "terraform-test"
host_system_id = "${data.vsphere_host.esxi_host.id}"
disks = [
"${var.disk0}",
]
custom_attributes = "${local.vmfs_attrs}"
}
`, os.Getenv("VSPHERE_DS_VMFS_DISK0"), os.Getenv("VSPHERE_DATACENTER"), os.Getenv("VSPHERE_ESXI_HOST"))
}

func testAccResourceVSphereVmfsDatastoreConfigMultiCustomAttributes() string {
return fmt.Sprintf(`
variable "disk0" {
type = "string"
default = "%s"
}
data "vsphere_datacenter" "datacenter" {
name = "%s"
}
data "vsphere_host" "esxi_host" {
name = "%s"
datacenter_id = "${data.vsphere_datacenter.datacenter.id}"
}
resource "vsphere_custom_attribute" "terraform-test-attribute" {
name = "terraform-test-attribute"
managed_object_type = "Datastore"
}
resource "vsphere_custom_attribute" "terraform-test-attribute-2" {
name = "terraform-test-attribute-2"
managed_object_type = "Datastore"
}
locals {
vmfs_attrs = {
"${vsphere_custom_attribute.terraform-test-attribute.id}" = "value"
"${vsphere_custom_attribute.terraform-test-attribute-2.id}" = "value-2"
}
}
resource "vsphere_vmfs_datastore" "datastore" {
name = "terraform-test"
host_system_id = "${data.vsphere_host.esxi_host.id}"
disks = [
"${var.disk0}",
]
custom_attributes = "${local.vmfs_attrs}"
}
`, os.Getenv("VSPHERE_DS_VMFS_DISK0"), os.Getenv("VSPHERE_DATACENTER"), os.Getenv("VSPHERE_ESXI_HOST"))
}
10 changes: 10 additions & 0 deletions website/docs/r/vmfs_datastore.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,16 @@ The following arguments are supported:
~> **NOTE:** Tagging support is unsupported on direct ESXi connections and
requires vCenter 6.0 or higher.

* `custom_attributes` (Optional) Map of custom attribute ids to attribute
value string to set on datastore resource. See
[here][docs-setting-custom-attributes] for a reference on how to set values
for custom attributes.

[docs-setting-custom-attributes]: /docs/providers/vsphere/r/custom_attribute.html#using-custom-attributes-in-a-supported-resource

~> **NOTE:** Custom attributes are unsupported on direct ESXi connections
and require vCenter.

## Attribute Reference

The following attributes are exported:
Expand Down

0 comments on commit 3e2ba87

Please sign in to comment.