Merge pull request #65 from cezarsa/tags

Add back support for tags in resources
diff --git a/README.md b/README.md
index 8bdbe38..46f1baf 100644
--- a/README.md
+++ b/README.md
@@ -56,8 +56,8 @@
 In order to run the full suite of Acceptance tests you will need to run the CloudStack Simulator. Please follow these steps to prepare an environment for running the Acceptance tests:
 
 ```sh
-$ docker pull svanharmelen/simulator:4.11.2.0
-$ docker run -d -p 8080:8080 --name cloudstack svanharmelen/simulator:4.11.2.0
+$ docker pull svanharmelen/simulator:4.12.0.0
+$ docker run -d -p 8080:8080 --name cloudstack svanharmelen/simulator:4.12.0.0
 ```
 
 When Docker started the container you can go to http://localhost:8080/client and login to the CloudStack UI as user `admin` with password `password`. It can take a few minutes for the container is fully ready, so you probably need to wait and refresh the page for a few minutes before the login page is shown.
diff --git a/cloudstack/data_source_cloudstack_template.go b/cloudstack/data_source_cloudstack_template.go
index e03958b..f68e841 100644
--- a/cloudstack/data_source_cloudstack_template.go
+++ b/cloudstack/data_source_cloudstack_template.go
@@ -63,7 +63,7 @@
 				Computed: true,
 			},
 
-			// "tags": tagsSchema(),
+			"tags": tagsSchema(),
 		},
 	}
 }
@@ -118,11 +118,11 @@
 	d.Set("name", template.Name)
 	d.Set("size", template.Size)
 
-	// tags := make(map[string]interface{})
-	// for _, tag := range template.Tags {
-	// 	tags[tag.Key] = tag.Value
-	// }
-	// d.Set("tags", tags)
+	tags := make(map[string]interface{})
+	for _, tag := range template.Tags {
+		tags[tag.Key] = tag.Value
+	}
+	d.Set("tags", tags)
 
 	return nil
 }
diff --git a/cloudstack/resource_cloudstack_disk.go b/cloudstack/resource_cloudstack_disk.go
index 42f0c45..cb9dac7 100644
--- a/cloudstack/resource_cloudstack_disk.go
+++ b/cloudstack/resource_cloudstack_disk.go
@@ -72,7 +72,7 @@
 				ForceNew: true,
 			},
 
-			// "tags": tagsSchema(),
+			"tags": tagsSchema(),
 		},
 	}
 }
@@ -131,11 +131,11 @@
 	d.SetId(r.Id)
 
 	// Set tags if necessary
-	// err = setTags(cs, d, "Volume")
-	// if err != nil {
-	// 	return fmt.Errorf("Error setting tags on the new disk %s: %s", name, err)
-	// }
-	// d.SetPartial("tags")
+	err = setTags(cs, d, "Volume")
+	if err != nil {
+		return fmt.Errorf("Error setting tags on the new disk %s: %s", name, err)
+	}
+	d.SetPartial("tags")
 
 	if d.Get("attach").(bool) {
 		if err := resourceCloudStackDiskAttach(d, meta); err != nil {
@@ -171,11 +171,11 @@
 	d.Set("attach", v.Virtualmachineid != "")   // If attached this contains a virtual machine ID
 	d.Set("size", int(v.Size/(1024*1024*1024))) // Needed to get GB's again
 
-	// tags := make(map[string]interface{})
-	// for _, tag := range v.Tags {
-	// 	tags[tag.Key] = tag.Value
-	// }
-	// d.Set("tags", tags)
+	tags := make(map[string]interface{})
+	for _, tag := range v.Tags {
+		tags[tag.Key] = tag.Value
+	}
+	d.Set("tags", tags)
 
 	setValueOrID(d, "disk_offering", v.Diskofferingname, v.Diskofferingid)
 	setValueOrID(d, "project", v.Project, v.Projectid)
@@ -261,13 +261,13 @@
 	}
 
 	// Check is the tags have changed and if so, update the tags
-	// if d.HasChange("tags") {
-	// 	err := updateTags(cs, d, "Volume")
-	// 	if err != nil {
-	// 		return fmt.Errorf("Error updating tags on disk %s: %s", name, err)
-	// 	}
-	// 	d.SetPartial("tags")
-	// }
+	if d.HasChange("tags") {
+		err := updateTags(cs, d, "Volume")
+		if err != nil {
+			return fmt.Errorf("Error updating tags on disk %s: %s", name, err)
+		}
+		d.SetPartial("tags")
+	}
 
 	d.Partial(false)
 
diff --git a/cloudstack/resource_cloudstack_disk_test.go b/cloudstack/resource_cloudstack_disk_test.go
index 19d9221..31da6ae 100644
--- a/cloudstack/resource_cloudstack_disk_test.go
+++ b/cloudstack/resource_cloudstack_disk_test.go
@@ -23,7 +23,7 @@
 					testAccCheckCloudStackDiskExists(
 						"cloudstack_disk.foo", &disk),
 					testAccCheckCloudStackDiskAttributes(&disk),
-					// testAccCheckResourceTags(&disk),
+					testAccCheckResourceTags(&disk),
 				),
 			},
 		},
@@ -187,9 +187,9 @@
   attach = false
   disk_offering = "Small"
   zone = "Sandbox-simulator"
-	#tags = {
-	#  terraform-tag = "true"
-	#}
+  tags = {
+    terraform-tag = "true"
+  }
 }`
 
 const testAccCloudStackDisk_update = `
diff --git a/cloudstack/resource_cloudstack_instance.go b/cloudstack/resource_cloudstack_instance.go
index 99cb2a9..0565902 100644
--- a/cloudstack/resource_cloudstack_instance.go
+++ b/cloudstack/resource_cloudstack_instance.go
@@ -152,7 +152,7 @@
 				Default:  false,
 			},
 
-			// "tags": tagsSchema(),
+			"tags": tagsSchema(),
 		},
 	}
 }
@@ -284,9 +284,9 @@
 	d.SetId(r.Id)
 
 	// Set tags if necessary
-	// if err = setTags(cs, d, "userVm"); err != nil {
-	// 	return fmt.Errorf("Error setting tags on the new instance %s: %s", name, err)
-	// }
+	if err = setTags(cs, d, "userVm"); err != nil {
+		return fmt.Errorf("Error setting tags on the new instance %s: %s", name, err)
+	}
 
 	// Set the connection info for any configured provisioners
 	d.SetConnInfo(map[string]string{
@@ -377,11 +377,11 @@
 		d.Set("security_group_names", groups)
 	}
 
-	// tags := make(map[string]interface{})
-	// for _, tag := range vm.Tags {
-	// 	tags[tag.Key] = tag.Value
-	// }
-	// d.Set("tags", tags)
+	tags := make(map[string]interface{})
+	for _, tag := range vm.Tags {
+		tags[tag.Key] = tag.Value
+	}
+	d.Set("tags", tags)
 
 	setValueOrID(d, "service_offering", vm.Serviceofferingname, vm.Serviceofferingid)
 	setValueOrID(d, "template", vm.Templatename, vm.Templateid)
@@ -580,12 +580,12 @@
 	}
 
 	// Check is the tags have changed and if so, update the tags
-	// if d.HasChange("tags") {
-	// 	if err := updateTags(cs, d, "UserVm"); err != nil {
-	// 		return fmt.Errorf("Error updating tags on instance %s: %s", name, err)
-	// 	}
-	// 	d.SetPartial("tags")
-	// }
+	if d.HasChange("tags") {
+		if err := updateTags(cs, d, "UserVm"); err != nil {
+			return fmt.Errorf("Error updating tags on instance %s: %s", name, err)
+		}
+		d.SetPartial("tags")
+	}
 
 	d.Partial(false)
 
diff --git a/cloudstack/resource_cloudstack_instance_test.go b/cloudstack/resource_cloudstack_instance_test.go
index 611545d..78b14e9 100644
--- a/cloudstack/resource_cloudstack_instance_test.go
+++ b/cloudstack/resource_cloudstack_instance_test.go
@@ -25,7 +25,7 @@
 					testAccCheckCloudStackInstanceAttributes(&instance),
 					resource.TestCheckResourceAttr(
 						"cloudstack_instance.foobar", "user_data", "0cf3dcdc356ec8369494cb3991985ecd5296cdd5"),
-					// testAccCheckResourceTags(&instance),
+					testAccCheckResourceTags(&instance),
 				),
 			},
 		},
@@ -307,9 +307,9 @@
   zone = "Sandbox-simulator"
   user_data = "foobar\nfoo\nbar"
   expunge = true
-  #tags = {
-  #  terraform-tag = "true"
-  #}
+  tags = {
+    terraform-tag = "true"
+  }
 }`
 
 const testAccCloudStackInstance_stopped = `
diff --git a/cloudstack/resource_cloudstack_ipaddress.go b/cloudstack/resource_cloudstack_ipaddress.go
index 6d8bfb7..bf0d5b8 100644
--- a/cloudstack/resource_cloudstack_ipaddress.go
+++ b/cloudstack/resource_cloudstack_ipaddress.go
@@ -53,7 +53,7 @@
 				Computed: true,
 			},
 
-			// "tags": tagsSchema(),
+			"tags": tagsSchema(),
 		},
 	}
 }
@@ -107,10 +107,10 @@
 	d.SetId(r.Id)
 
 	// Set tags if necessary
-	// err = setTags(cs, d, "PublicIpAddress")
-	// if err != nil {
-	// 	return fmt.Errorf("Error setting tags on the IP address: %s", err)
-	// }
+	err = setTags(cs, d, "PublicIpAddress")
+	if err != nil {
+		return fmt.Errorf("Error setting tags on the IP address: %s", err)
+	}
 
 	return resourceCloudStackIPAddressRead(d, meta)
 }
@@ -151,11 +151,11 @@
 		setValueOrID(d, "zone", ip.Zonename, ip.Zoneid)
 	}
 
-	// tags := make(map[string]interface{})
-	// for _, tag := range ip.Tags {
-	// 	tags[tag.Key] = tag.Value
-	// }
-	// d.Set("tags", tags)
+	tags := make(map[string]interface{})
+	for _, tag := range ip.Tags {
+		tags[tag.Key] = tag.Value
+	}
+	d.Set("tags", tags)
 
 	setValueOrID(d, "project", ip.Project, ip.Projectid)
 
diff --git a/cloudstack/resource_cloudstack_ipaddress_test.go b/cloudstack/resource_cloudstack_ipaddress_test.go
index 053d4ee..19b1bf4 100644
--- a/cloudstack/resource_cloudstack_ipaddress_test.go
+++ b/cloudstack/resource_cloudstack_ipaddress_test.go
@@ -22,7 +22,7 @@
 				Check: resource.ComposeTestCheckFunc(
 					testAccCheckCloudStackIPAddressExists(
 						"cloudstack_ipaddress.foo", &ipaddr),
-					// testAccCheckResourceTags(&ipaddr),
+					testAccCheckResourceTags(&ipaddr),
 				),
 			},
 		},
@@ -109,9 +109,9 @@
 
 resource "cloudstack_ipaddress" "foo" {
   network_id = "${cloudstack_network.foo.id}"
-  #tags = {
-  #  terraform-tag = "true"
-  #}
+  tags = {
+    terraform-tag = "true"
+  }
 }`
 
 const testAccCloudStackIPAddress_vpc = `
diff --git a/cloudstack/resource_cloudstack_network.go b/cloudstack/resource_cloudstack_network.go
index b10c675..4577cef 100644
--- a/cloudstack/resource_cloudstack_network.go
+++ b/cloudstack/resource_cloudstack_network.go
@@ -129,7 +129,7 @@
 				ForceNew: true,
 			},
 
-			// "tags": tagsSchema(),
+			"tags": tagsSchema(),
 		},
 	}
 }
@@ -235,10 +235,10 @@
 	d.SetId(r.Id)
 
 	// Set tags if necessary
-	// if err = setTags(cs, d, "network"); err != nil {
-	// 	return fmt.Errorf("Error setting tags: %v", err)
-	// }
-	// d.SetPartial("tags")
+	if err = setTags(cs, d, "network"); err != nil {
+		return fmt.Errorf("Error setting tags: %v", err)
+	}
+	d.SetPartial("tags")
 
 	if d.Get("source_nat_ip").(bool) {
 		// Create a new parameter struct
@@ -305,11 +305,11 @@
 	}
 	d.Set("acl_id", n.Aclid)
 
-	// tags := make(map[string]interface{})
-	// for _, tag := range n.Tags {
-	// 	tags[tag.Key] = tag.Value
-	// }
-	// d.Set("tags", tags)
+	tags := make(map[string]interface{})
+	for _, tag := range n.Tags {
+		tags[tag.Key] = tag.Value
+	}
+	d.Set("tags", tags)
 
 	setValueOrID(d, "network_offering", n.Networkofferingname, n.Networkofferingid)
 	setValueOrID(d, "project", n.Project, n.Projectid)
@@ -400,11 +400,11 @@
 	}
 
 	// Update tags if they have changed
-	// if d.HasChange("tags") {
-	// 	if err := updateTags(cs, d, "Network"); err != nil {
-	// 		return fmt.Errorf("Error updating tags on ACL %s: %s", name, err)
-	// 	}
-	// }
+	if d.HasChange("tags") {
+		if err := updateTags(cs, d, "Network"); err != nil {
+			return fmt.Errorf("Error updating tags on ACL %s: %s", name, err)
+		}
+	}
 
 	return resourceCloudStackNetworkRead(d, meta)
 }
diff --git a/cloudstack/resource_cloudstack_network_test.go b/cloudstack/resource_cloudstack_network_test.go
index 144bfef..0ef874e 100644
--- a/cloudstack/resource_cloudstack_network_test.go
+++ b/cloudstack/resource_cloudstack_network_test.go
@@ -23,7 +23,7 @@
 					testAccCheckCloudStackNetworkExists(
 						"cloudstack_network.foo", &network),
 					testAccCheckCloudStackNetworkBasicAttributes(&network),
-					// testAccCheckResourceTags(&network),
+					testAccCheckResourceTags(&network),
 				),
 			},
 		},
@@ -245,9 +245,9 @@
   cidr = "10.1.1.0/24"
   network_offering = "DefaultIsolatedNetworkOfferingWithSourceNatService"
   zone = "Sandbox-simulator"
-  #tags = {
-  #  terraform-tag = "true"
-  #}
+  tags = {
+    terraform-tag = "true"
+  }
 }`
 
 const testAccCloudStackNetwork_project = `
diff --git a/cloudstack/resource_cloudstack_template.go b/cloudstack/resource_cloudstack_template.go
index dcc4b40..5e76f41 100644
--- a/cloudstack/resource_cloudstack_template.go
+++ b/cloudstack/resource_cloudstack_template.go
@@ -107,7 +107,7 @@
 				Default:  300,
 			},
 
-			// "tags": tagsSchema(),
+			"tags": tagsSchema(),
 		},
 	}
 }
@@ -187,9 +187,9 @@
 	d.SetId(r.RegisterTemplate[0].Id)
 
 	// Set tags if necessary
-	// if err = setTags(cs, d, "Template"); err != nil {
-	// 	return fmt.Errorf("Error setting tags on the template %s: %s", name, err)
-	// }
+	if err = setTags(cs, d, "Template"); err != nil {
+		return fmt.Errorf("Error setting tags on the template %s: %s", name, err)
+	}
 
 	// Wait until the template is ready to use, or timeout with an error...
 	currentTime := time.Now().Unix()
@@ -245,11 +245,11 @@
 	d.Set("password_enabled", t.Passwordenabled)
 	d.Set("is_ready", t.Isready)
 
-	// tags := make(map[string]interface{})
-	// for _, tag := range t.Tags {
-	// 	tags[tag.Key] = tag.Value
-	// }
-	// d.Set("tags", tags)
+	tags := make(map[string]interface{})
+	for _, tag := range t.Tags {
+		tags[tag.Key] = tag.Value
+	}
+	d.Set("tags", tags)
 
 	setValueOrID(d, "os_type", t.Ostypename, t.Ostypeid)
 	setValueOrID(d, "project", t.Project, t.Projectid)
@@ -298,11 +298,11 @@
 		return fmt.Errorf("Error updating template %s: %s", name, err)
 	}
 
-	// if d.HasChange("tags") {
-	// 	if err := updateTags(cs, d, "Template"); err != nil {
-	// 		return fmt.Errorf("Error updating tags on template %s: %s", name, err)
-	// 	}
-	// }
+	if d.HasChange("tags") {
+		if err := updateTags(cs, d, "Template"); err != nil {
+			return fmt.Errorf("Error updating tags on template %s: %s", name, err)
+		}
+	}
 
 	return resourceCloudStackTemplateRead(d, meta)
 }
diff --git a/cloudstack/resource_cloudstack_template_test.go b/cloudstack/resource_cloudstack_template_test.go
index 449a3dc..0c1fb61 100644
--- a/cloudstack/resource_cloudstack_template_test.go
+++ b/cloudstack/resource_cloudstack_template_test.go
@@ -175,9 +175,9 @@
   os_type = "Centos 5.6 (64-bit)"
   url = "%s"
   zone = "Sandbox-simulator"
-  #tags = {
-  #  terraform-tag = "true"
-  #}
+  tags = {
+    terraform-tag = "true"
+  }
 }`, CLOUDSTACK_TEMPLATE_URL)
 
 var testAccCloudStackTemplate_update = fmt.Sprintf(`
diff --git a/cloudstack/resource_cloudstack_vpc_test.go b/cloudstack/resource_cloudstack_vpc_test.go
index 20cfad3..fe98a62 100644
--- a/cloudstack/resource_cloudstack_vpc_test.go
+++ b/cloudstack/resource_cloudstack_vpc_test.go
@@ -25,7 +25,7 @@
 					testAccCheckCloudStackVPCAttributes(&vpc),
 					resource.TestCheckResourceAttr(
 						"cloudstack_vpc.foo", "vpc_offering", "Default VPC offering"),
-					// testAccCheckResourceTags(&vpc),
+					testAccCheckResourceTags(&vpc),
 				),
 			},
 		},
diff --git a/cloudstack/tags_test.go b/cloudstack/tags_test.go
index 302cda9..cdd3f97 100644
--- a/cloudstack/tags_test.go
+++ b/cloudstack/tags_test.go
@@ -3,10 +3,11 @@
 import (
 	"encoding/json"
 	"fmt"
-	"github.com/hashicorp/terraform/helper/resource"
-	"github.com/hashicorp/terraform/terraform"
 	"reflect"
 	"testing"
+
+	"github.com/hashicorp/terraform/helper/resource"
+	"github.com/hashicorp/terraform/terraform"
 )
 
 func TestDiffTags(t *testing.T) {
@@ -61,15 +62,15 @@
 // testAccCheckResourceTags is an helper to test tags creation on any resource.
 func testAccCheckResourceTags(
 	n interface{}) resource.TestCheckFunc {
-	b, _ := json.Marshal(n)
 	res := struct {
 		Tags []struct {
 			Key   string `json:"key,omitempty"`
 			Value string `json:"value,omitempty"`
 		} `json:"tags,omitempty"`
 	}{}
-	json.Unmarshal(b, &res)
 	return func(s *terraform.State) error {
+		b, _ := json.Marshal(n)
+		json.Unmarshal(b, &res)
 		tags := make(map[string]string)
 		for _, tag := range res.Tags {
 			tags[tag.Key] = tag.Value