Add support for volume tags (#336)

* add support for volume tags

* update tags datasource schema & utilize flattenTags

Co-Authored-By: Andrew Starr-Bochicchio <andrewsomething@users.noreply.github.com>
This commit is contained in:
aqche 2019-11-19 11:06:41 -06:00 committed by Andrew Starr-Bochicchio
parent 1f2c14aeb1
commit 6a10ef7439
8 changed files with 70 additions and 5 deletions

View File

@ -63,6 +63,7 @@ func dataSourceDigitalOceanVolume() *schema.Resource {
Computed: true,
Description: "list of droplet ids the volume is attached to",
},
"tags": tagsDataSourceSchema(),
},
}
}
@ -120,6 +121,7 @@ func dataSourceDigitalOceanVolumeRead(d *schema.ResourceData, meta interface{})
d.Set("urn", volume.URN())
d.Set("region", volume.Region.Slug)
d.Set("size", int(volume.SizeGigaBytes))
d.Set("tags", flattenTags(volume.Tags))
if v := volume.Description; v != "" {
d.Set("description", v)

View File

@ -34,6 +34,8 @@ func TestAccDataSourceDigitalOceanVolume_Basic(t *testing.T) {
"data.digitalocean_volume.foobar", "size", "10"),
resource.TestCheckResourceAttr(
"data.digitalocean_volume.foobar", "droplet_ids.#", "0"),
resource.TestCheckResourceAttr(
"data.digitalocean_volume.foobar", "tags.#", "2"),
resource.TestMatchResourceAttr("data.digitalocean_volume.foobar", "urn", expectedURNRegEx),
),
},
@ -61,6 +63,8 @@ func TestAccDataSourceDigitalOceanVolume_RegionScoped(t *testing.T) {
"data.digitalocean_volume.foobar", "size", "20"),
resource.TestCheckResourceAttr(
"data.digitalocean_volume.foobar", "droplet_ids.#", "0"),
resource.TestCheckResourceAttr(
"data.digitalocean_volume.foobar", "tags.#", "0"),
),
},
},
@ -103,6 +107,7 @@ resource "digitalocean_volume" "foo" {
region = "nyc3"
name = "volume-%d"
size = 10
tags = ["foo","bar"]
}
data "digitalocean_volume" "foobar" {
@ -116,6 +121,7 @@ resource "digitalocean_volume" "foo" {
region = "nyc3"
name = "volume-%d"
size = 10
tags = ["foo","bar"]
}
resource "digitalocean_volume" "bar" {

View File

@ -555,7 +555,7 @@ func resourceDigitalOceanDropletUpdate(d *schema.ResourceData, meta interface{})
}
if d.HasChange("tags") {
err = setTags(client, d)
err = setTags(client, d, godo.DropletResourceType)
if err != nil {
return fmt.Errorf("Error updating tags: %s", err)
}

View File

@ -102,6 +102,8 @@ func resourceDigitalOceanVolume() *schema.Resource {
Type: schema.TypeString,
Computed: true,
},
"tags": tagsSchema(),
},
CustomizeDiff: func(diff *schema.ResourceDiff, v interface{}) error {
@ -124,6 +126,7 @@ func resourceDigitalOceanVolumeCreate(d *schema.ResourceData, meta interface{})
opts := &godo.VolumeCreateRequest{
Name: d.Get("name").(string),
Description: d.Get("description").(string),
Tags: expandTags(d.Get("tags").(*schema.Set).List()),
}
if v, ok := d.GetOk("region"); ok {
@ -179,6 +182,13 @@ func resourceDigitalOceanVolumeUpdate(d *schema.ResourceData, meta interface{})
}
}
if d.HasChange("tags") {
err := setTags(client, d, godo.VolumeResourceType)
if err != nil {
return fmt.Errorf("Error updating tags: %s", err)
}
}
return resourceDigitalOceanVolumeRead(d, meta)
}
@ -201,6 +211,7 @@ func resourceDigitalOceanVolumeRead(d *schema.ResourceData, meta interface{}) er
d.Set("region", volume.Region.Slug)
d.Set("size", int(volume.SizeGigaBytes))
d.Set("urn", volume.URN())
d.Set("tags", flattenTags(volume.Tags))
if v := volume.Description; v != "" {
d.Set("description", v)

View File

@ -93,6 +93,8 @@ func TestAccDigitalOceanVolume_Basic(t *testing.T) {
"digitalocean_volume.foobar", "region", "nyc1"),
resource.TestCheckResourceAttr(
"digitalocean_volume.foobar", "description", "peace makes plenty"),
resource.TestCheckResourceAttr(
"digitalocean_volume.foobar", "tags.#", "2"),
resource.TestMatchResourceAttr("digitalocean_volume.foobar", "urn", expectedURNRegEx),
),
},
@ -106,6 +108,7 @@ resource "digitalocean_volume" "foobar" {
name = "%s"
size = 100
description = "peace makes plenty"
tags = ["foo","bar"]
}`
func testAccCheckDigitalOceanVolumeExists(rn string, volume *godo.Volume) resource.TestCheckFunc {
@ -389,3 +392,44 @@ resource "digitalocean_volume" "foobar" {
snapshot_id = "${digitalocean_volume_snapshot.foo.id}"
}`, rInt, rInt, rInt)
}
func TestAccDigitalOceanVolume_UpdateTags(t *testing.T) {
name := fmt.Sprintf("volume-%s", acctest.RandString(10))
volume := godo.Volume{
Name: name,
}
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckDigitalOceanVolumeDestroy,
Steps: []resource.TestStep{
{
Config: fmt.Sprintf(testAccCheckDigitalOceanVolumeConfig_basic, name),
Check: resource.ComposeTestCheckFunc(
testAccCheckDigitalOceanVolumeExists("digitalocean_volume.foobar", &volume),
resource.TestCheckResourceAttr(
"digitalocean_volume.foobar", "tags.#", "2"),
),
},
{
Config: fmt.Sprintf(testAccCheckDigitalOceanVolumeConfig_basic_tag_update, name),
Check: resource.ComposeTestCheckFunc(
testAccCheckDigitalOceanVolumeExists("digitalocean_volume.foobar", &volume),
resource.TestCheckResourceAttr(
"digitalocean_volume.foobar", "tags.#", "3"),
),
},
},
})
}
const testAccCheckDigitalOceanVolumeConfig_basic_tag_update = `
resource "digitalocean_volume" "foobar" {
region = "nyc1"
name = "%s"
size = 100
description = "peace makes plenty"
tags = ["foo","bar","baz"]
}`

View File

@ -42,7 +42,7 @@ func validateTag(value interface{}, key string) ([]string, []error) {
// setTags is a helper to set the tags for a resource. It expects the
// tags field to be named "tags"
func setTags(conn *godo.Client, d *schema.ResourceData) error {
func setTags(conn *godo.Client, d *schema.ResourceData, resourceType godo.ResourceType) error {
oraw, nraw := d.GetChange("tags")
remove, create := diffTags(tagsFromSchema(oraw), tagsFromSchema(nraw))
@ -52,7 +52,7 @@ func setTags(conn *godo.Client, d *schema.ResourceData) error {
Resources: []godo.Resource{
{
ID: d.Id(),
Type: godo.DropletResourceType,
Type: resourceType,
},
},
})
@ -75,7 +75,7 @@ func setTags(conn *godo.Client, d *schema.ResourceData) error {
Resources: []godo.Resource{
{
ID: d.Id(),
Type: godo.DropletResourceType,
Type: resourceType,
},
},
})

View File

@ -64,4 +64,5 @@ The following attributes are exported:
* `description` - Text describing a block storage volume.
* `filesystem_type` - Filesystem type currently in-use on the block storage volume.
* `filesystem_label` - Filesystem label currently in-use on the block storage volume.
* `droplet_ids` - A list of associated Droplet ids.
* `droplet_ids` - A list of associated Droplet ids.
* `tags` - A list of the tags associated to the Volume.

View File

@ -60,6 +60,7 @@ The following arguments are supported:
* `snapshot_id` - (Optional) The ID of an existing volume snapshot from which the new volume will be created. If supplied, the region and size will be limitied on creation to that of the referenced snapshot
* `initial_filesystem_type` - (Optional) Initial filesystem type (`xfs` or `ext4`) for the block storage volume.
* `initial_filesystem_label` - (Optional) Initial filesystem label for the block storage volume.
* `tags` - (Optional) A list of the tags to be applied to this Volume.
## Attributes Reference