diff --git a/random/resource_string.go b/random/resource_string.go index 86025aa42..9aca8353d 100644 --- a/random/resource_string.go +++ b/random/resource_string.go @@ -11,10 +11,11 @@ import ( func resourceString() *schema.Resource { return &schema.Resource{ - Create: CreateString, - Read: ReadString, - Delete: schema.RemoveFromState, - + Create: CreateString, + Read: ReadString, + Delete: schema.RemoveFromState, + MigrateState: resourceRandomStringMigrateState, + SchemaVersion: 1, Schema: map[string]*schema.Schema{ "keepers": { Type: schema.TypeMap, diff --git a/random/resource_string_migration.go b/random/resource_string_migration.go new file mode 100644 index 000000000..a39916df9 --- /dev/null +++ b/random/resource_string_migration.go @@ -0,0 +1,48 @@ +package random + +import ( + "fmt" + "log" + + "github.com/hashicorp/terraform/terraform" +) + +func resourceRandomStringMigrateState( + v int, is *terraform.InstanceState, meta interface{}) (*terraform.InstanceState, error) { + switch v { + case 0: + log.Println("[INFO] Found random string state v0; migrating to v1") + return migrateStringStateV0toV1(is) + default: + return is, fmt.Errorf("Unexpected schema version: %d", v) + } +} + +func redactAttributes(is *terraform.InstanceState) map[string]string { + redactedAttributes := make(map[string]string) + for k, v := range is.Attributes { + redactedAttributes[k] = v + if k == "id" || k == "result" { + redactedAttributes[k] = "" + } + } + return redactedAttributes +} + +func migrateStringStateV0toV1(is *terraform.InstanceState) (*terraform.InstanceState, error) { + if is.Empty() { + log.Println("[DEBUG] Empty InstanceState; nothing to migrate.") + return is, nil + } + + log.Printf("[DEBUG] Random String Attributes before Migration: %#v", redactAttributes(is)) + + is.Attributes["min_numeric"] = "0" + is.Attributes["min_upper"] = "0" + is.Attributes["min_lower"] = "0" + is.Attributes["min_special"] = "0" + + log.Printf("[DEBUG] Random String Attributes after State Migration: %#v", redactAttributes(is)) + + return is, nil +} diff --git a/random/resource_string_migration_test.go b/random/resource_string_migration_test.go new file mode 100644 index 000000000..fb3e39c1f --- /dev/null +++ b/random/resource_string_migration_test.go @@ -0,0 +1,77 @@ +package random + +import ( + "testing" + + "github.com/hashicorp/terraform/terraform" +) + +func TestResourceStringMigrateState(t *testing.T) { + cases := map[string]struct { + StateVersion int + ID string + InputAttributes map[string]string + ExpectedAttributes map[string]string + Meta interface{} + }{ + "v0_1_simple": { + StateVersion: 0, + ID: "some_id", + InputAttributes: map[string]string{ + "result": "foo", + "id": "foo", + "length": "3", + }, + ExpectedAttributes: map[string]string{ + "result": "foo", + "id": "foo", + "length": "3", + "min_numeric": "0", + "min_special": "0", + "min_lower": "0", + "min_upper": "0", + }, + }, + "v0_1_special": { + StateVersion: 0, + ID: "some_id", + InputAttributes: map[string]string{ + "result": "foo", + "id": "foo", + "special": "false", + "length": "3", + "override_special": "!@", + }, + ExpectedAttributes: map[string]string{ + "result": "foo", + "id": "foo", + "special": "false", + "length": "3", + "override_special": "!@", + "min_numeric": "0", + "min_special": "0", + "min_lower": "0", + "min_upper": "0", + }, + }, + } + + for tn, tc := range cases { + is := &terraform.InstanceState{ + ID: tc.ID, + Attributes: tc.InputAttributes, + } + is, err := resourceRandomStringMigrateState(tc.StateVersion, is, tc.Meta) + + if err != nil { + t.Fatalf("bad: %s, err: %#v", tn, err) + } + + for k, v := range tc.ExpectedAttributes { + actual := is.Attributes[k] + if actual != v { + t.Fatalf("Bad Random String Migration for %q: %q\n\n expected: %q", k, actual, v) + } + } + } +}