From 56901e5cfd962628582d66def9e163375faa7c1d Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Tue, 27 Sep 2016 16:09:32 -0700 Subject: [PATCH] terraform: ResourceConfig.DeepCopy This implements DeepCopy, still need to implement Equals to make this more useful. Coming in the next commit but this still has its own full functionality + tests. --- terraform/resource.go | 20 ++++++++++++++++++++ terraform/resource_test.go | 14 ++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/terraform/resource.go b/terraform/resource.go index 795bd9672c..6661fa3f04 100644 --- a/terraform/resource.go +++ b/terraform/resource.go @@ -7,6 +7,7 @@ import ( "strings" "github.com/hashicorp/terraform/config" + "github.com/mitchellh/copystructure" ) // ResourceProvisionerConfig is used to pair a provisioner @@ -93,6 +94,25 @@ func NewResourceConfig(c *config.RawConfig) *ResourceConfig { return result } +// DeepCopy performs a deep copy of the configuration. This makes it safe +// to modify any of the structures that are part of the resource config without +// affecting the original configuration. +func (c *ResourceConfig) DeepCopy() *ResourceConfig { + // Copy, this will copy all the exported attributes + copy, err := copystructure.Config{Lock: true}.Copy(c) + if err != nil { + panic(err) + } + + // Force the type + result := copy.(*ResourceConfig) + + // For the raw configuration, we can just use its own copy method + result.raw = c.raw.Copy() + + return result +} + // CheckSet checks that the given list of configuration keys is // properly set. If not, errors are returned for each unset key. // diff --git a/terraform/resource_test.go b/terraform/resource_test.go index dba1636a29..3171a40a20 100644 --- a/terraform/resource_test.go +++ b/terraform/resource_test.go @@ -1,6 +1,7 @@ package terraform import ( + "fmt" "reflect" "testing" @@ -212,6 +213,19 @@ func TestResourceConfigGet(t *testing.T) { if !reflect.DeepEqual(v, tc.Value) { t.Fatalf("%d bad: %#v", i, v) } + + // If we have vars, we don't test copying + if len(tc.Vars) > 0 { + continue + } + + // Test copying + t.Run(fmt.Sprintf("copy-%d", i), func(t *testing.T) { + copy := rc.DeepCopy() + if !reflect.DeepEqual(copy, rc) { + t.Fatalf("bad:\n\n%#v\n\n%#v", copy, rc) + } + }) } }