Skip to content

Commit

Permalink
Add custom attribute support to NAS datastore resource
Browse files Browse the repository at this point in the history
  • Loading branch information
rmbrad committed Dec 18, 2017
1 parent 3e2ba87 commit 9116fb9
Show file tree
Hide file tree
Showing 5 changed files with 198 additions and 3 deletions.
4 changes: 2 additions & 2 deletions vsphere/helper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -510,8 +510,8 @@ func testGetDatastore(s *terraform.State, resAddr string) (*object.Datastore, er

// 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)
func testGetDatastoreProperties(s *terraform.State, datastoreType string, resourceName string) (*mo.Datastore, error) {
ds, err := testGetDatastore(s, "vsphere_"+datastoreType+"_datastore."+resourceName)
if err != nil {
return nil, err
}
Expand Down
32 changes: 32 additions & 0 deletions vsphere/resource_vsphere_nas_datastore.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"

"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 @@ -42,6 +43,8 @@ func resourceVSphereNasDatastore() *schema.Resource {

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

return &schema.Resource{
Create: resourceVSphereNasDatastoreCreate,
Expand All @@ -64,6 +67,11 @@ func resourceVSphereNasDatastoreCreate(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
}

hosts := structure.SliceInterfacesToStrings(d.Get("host_system_ids").(*schema.Set).List())
p := &nasDatastoreMountProcessor{
Expand Down Expand Up @@ -95,6 +103,13 @@ func resourceVSphereNasDatastoreCreate(d *schema.ResourceData, meta interface{})
}
}

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

// Done
return resourceVSphereNasDatastoreRead(d, meta)
}
Expand Down Expand Up @@ -142,6 +157,11 @@ func resourceVSphereNasDatastoreRead(d *schema.ResourceData, meta interface{}) e
}
}

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

return nil
}

Expand All @@ -154,6 +174,11 @@ func resourceVSphereNasDatastoreUpdate(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
}

id := d.Id()
ds, err := datastore.FromID(client, id)
Expand Down Expand Up @@ -183,6 +208,13 @@ func resourceVSphereNasDatastoreUpdate(d *schema.ResourceData, meta interface{})
}
}

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

// Process mount/unmount operations.
o, n := d.GetChange("host_system_ids")

Expand Down
153 changes: 153 additions & 0 deletions vsphere/resource_vsphere_nas_datastore_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,53 @@ func TestAccResourceVSphereNasDatastore(t *testing.T) {
},
},
},
{
"single custom attribute",
resource.TestCase{
PreCheck: func() {
testAccPreCheck(tp)
testAccResourceVSphereNasDatastorePreCheck(tp)
},
Providers: testAccProviders,
CheckDestroy: testAccResourceVSphereNasDatastoreExists(false),
Steps: []resource.TestStep{
{
Config: testAccResourceVSphereNasDatastoreConfigSingleCustomAttribute(),
Check: resource.ComposeTestCheckFunc(
testAccResourceVSphereNasDatastoreExists(true),
testAccResourceVSphereNasDatastoreHasCustomAttributes(),
),
},
},
},
},
{
"multi custom attribute",
resource.TestCase{
PreCheck: func() {
testAccPreCheck(tp)
testAccResourceVSphereNasDatastorePreCheck(tp)
},
Providers: testAccProviders,
CheckDestroy: testAccResourceVSphereNasDatastoreExists(false),
Steps: []resource.TestStep{
{
Config: testAccResourceVSphereNasDatastoreConfigSingleCustomAttribute(),
Check: resource.ComposeTestCheckFunc(
testAccResourceVSphereNasDatastoreExists(true),
testAccResourceVSphereNasDatastoreHasCustomAttributes(),
),
},
{
Config: testAccResourceVSphereNasDatastoreConfigMultiCustomAttributes(),
Check: resource.ComposeTestCheckFunc(
testAccResourceVSphereNasDatastoreExists(true),
testAccResourceVSphereNasDatastoreHasCustomAttributes(),
),
},
},
},
},
}

for _, tc := range testAccResourceVSphereNasDatastoreCases {
Expand Down Expand Up @@ -345,6 +392,16 @@ func testAccResourceVSphereNasDatastoreMatchInventoryPath(expected string) resou
}
}

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

func testAccResourceVSphereNasDatastoreConfigBasic() string {
return fmt.Sprintf(`
variable "nfs_host" {
Expand Down Expand Up @@ -596,3 +653,99 @@ resource "vsphere_nas_datastore" "datastore" {
}
`, os.Getenv("VSPHERE_NAS_HOST"), os.Getenv("VSPHERE_NFS_PATH"), os.Getenv("VSPHERE_DATACENTER"), os.Getenv("VSPHERE_ESXI_HOST"))
}

func testAccResourceVSphereNasDatastoreConfigSingleCustomAttribute() string {
return fmt.Sprintf(`
variable "nfs_host" {
type = "string"
default = "%s"
}
variable "nfs_path" {
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 {
nas_attrs = {
"${vsphere_custom_attribute.terraform-test-attribute.id}" = "value"
}
}
resource "vsphere_nas_datastore" "datastore" {
name = "terraform-test-nas"
host_system_ids = ["${data.vsphere_host.esxi_host.id}"]
type = "NFS"
remote_hosts = ["${var.nfs_host}"]
remote_path = "${var.nfs_path}"
custom_attributes = "${local.nas_attrs}"
}
`, os.Getenv("VSPHERE_NAS_HOST"), os.Getenv("VSPHERE_NFS_PATH"), os.Getenv("VSPHERE_DATACENTER"), os.Getenv("VSPHERE_ESXI_HOST"))
}

func testAccResourceVSphereNasDatastoreConfigMultiCustomAttributes() string {
return fmt.Sprintf(`
variable "nfs_host" {
type = "string"
default = "%s"
}
variable "nfs_path" {
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 {
nas_attrs = {
"${vsphere_custom_attribute.terraform-test-attribute.id}" = "value"
"${vsphere_custom_attribute.terraform-test-attribute-2.id}" = "value-2"
}
}
resource "vsphere_nas_datastore" "datastore" {
name = "terraform-test-nas"
host_system_ids = ["${data.vsphere_host.esxi_host.id}"]
type = "NFS"
remote_hosts = ["${var.nfs_host}"]
remote_path = "${var.nfs_path}"
custom_attributes = "${local.nas_attrs}"
}
`, os.Getenv("VSPHERE_NAS_HOST"), os.Getenv("VSPHERE_NFS_PATH"), os.Getenv("VSPHERE_DATACENTER"), os.Getenv("VSPHERE_ESXI_HOST"))
}
2 changes: 1 addition & 1 deletion vsphere/resource_vsphere_vmfs_datastore_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ func testAccResourceVSphereVmfsDatastoreMatchInventoryPath(expected string) reso

func testAccResourceVSphereVmfsDatastoreHasCustomAttributes() resource.TestCheckFunc {
return func(s *terraform.State) error {
props, err := testGetDatastoreProperties(s, "datastore")
props, err := testGetDatastoreProperties(s, "vmfs", "datastore")
if err != nil {
return err
}
Expand Down
10 changes: 10 additions & 0 deletions website/docs/r/nas_datastore.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,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 strings to set on datasource 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 9116fb9

Please sign in to comment.