-
Notifications
You must be signed in to change notification settings - Fork 9.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #4787 from hashicorp/phinze/fix-consul-keys-update
consul: Fix several problems w/ consul_keys update
- Loading branch information
Showing
6 changed files
with
256 additions
and
74 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
package consul | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
"strings" | ||
|
||
"github.com/hashicorp/terraform/helper/schema" | ||
"github.com/hashicorp/terraform/terraform" | ||
) | ||
|
||
func resourceConsulKeysMigrateState( | ||
v int, is *terraform.InstanceState, meta interface{}) (*terraform.InstanceState, error) { | ||
switch v { | ||
case 0: | ||
log.Println("[INFO] Found consul_keys State v0; migrating to v1") | ||
return resourceConsulKeysMigrateStateV0toV1(is) | ||
default: | ||
return is, fmt.Errorf("Unexpected schema version: %d", v) | ||
} | ||
} | ||
|
||
func resourceConsulKeysMigrateStateV0toV1(is *terraform.InstanceState) (*terraform.InstanceState, error) { | ||
if is.Empty() || is.Attributes == nil { | ||
log.Println("[DEBUG] Empty InstanceState; nothing to migrate.") | ||
return is, nil | ||
} | ||
|
||
log.Printf("[DEBUG] Attributes before migration: %#v", is.Attributes) | ||
|
||
res := resourceConsulKeys() | ||
keys, err := readV0Keys(is, res) | ||
if err != nil { | ||
return is, err | ||
} | ||
if err := clearV0Keys(is); err != nil { | ||
return is, err | ||
} | ||
if err := writeV1Keys(is, res, keys); err != nil { | ||
return is, err | ||
} | ||
|
||
log.Printf("[DEBUG] Attributes after migration: %#v", is.Attributes) | ||
return is, nil | ||
} | ||
|
||
func readV0Keys( | ||
is *terraform.InstanceState, | ||
res *schema.Resource, | ||
) (*schema.Set, error) { | ||
reader := &schema.MapFieldReader{ | ||
Schema: res.Schema, | ||
Map: schema.BasicMapReader(is.Attributes), | ||
} | ||
result, err := reader.ReadField([]string{"key"}) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
oldKeys, ok := result.Value.(*schema.Set) | ||
if !ok { | ||
return nil, fmt.Errorf("Got unexpected value from state: %#v", result.Value) | ||
} | ||
return oldKeys, nil | ||
} | ||
|
||
func clearV0Keys(is *terraform.InstanceState) error { | ||
for k := range is.Attributes { | ||
if strings.HasPrefix(k, "key.") { | ||
delete(is.Attributes, k) | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func writeV1Keys( | ||
is *terraform.InstanceState, | ||
res *schema.Resource, | ||
keys *schema.Set, | ||
) error { | ||
writer := schema.MapFieldWriter{ | ||
Schema: res.Schema, | ||
} | ||
if err := writer.WriteField([]string{"key"}, keys); err != nil { | ||
return err | ||
} | ||
for k, v := range writer.Map() { | ||
is.Attributes[k] = v | ||
} | ||
|
||
return nil | ||
} |
90 changes: 90 additions & 0 deletions
90
builtin/providers/consul/resource_consul_keys_migrate_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
package consul | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/hashicorp/terraform/terraform" | ||
) | ||
|
||
func TestConsulKeysMigrateState(t *testing.T) { | ||
cases := map[string]struct { | ||
StateVersion int | ||
Attributes map[string]string | ||
Expected map[string]string | ||
Meta interface{} | ||
}{ | ||
"v0.6.9 and earlier, with old values hash function": { | ||
StateVersion: 0, | ||
Attributes: map[string]string{ | ||
"key.#": "2", | ||
"key.12345.name": "hello", | ||
"key.12345.path": "foo/bar", | ||
"key.12345.value": "world", | ||
"key.12345.default": "", | ||
"key.12345.delete": "false", | ||
"key.6789.name": "temp", | ||
"key.6789.path": "foo/foo", | ||
"key.6789.value": "", | ||
"key.6789.default": "", | ||
"key.6789.delete": "true", | ||
}, | ||
Expected: map[string]string{ | ||
"key.#": "2", | ||
"key.2401383718.default": "", | ||
"key.2401383718.delete": "true", | ||
"key.2401383718.name": "temp", | ||
"key.2401383718.path": "foo/foo", | ||
"key.2401383718.value": "", | ||
"key.3116955509.path": "foo/bar", | ||
"key.3116955509.default": "", | ||
"key.3116955509.delete": "false", | ||
"key.3116955509.name": "hello", | ||
"key.3116955509.value": "world", | ||
}, | ||
}, | ||
} | ||
|
||
for tn, tc := range cases { | ||
is := &terraform.InstanceState{ | ||
ID: "consul", | ||
Attributes: tc.Attributes, | ||
} | ||
is, err := resourceConsulKeys().MigrateState( | ||
tc.StateVersion, is, tc.Meta) | ||
|
||
if err != nil { | ||
t.Fatalf("bad: %s, err: %#v", tn, err) | ||
} | ||
|
||
for k, v := range tc.Expected { | ||
if is.Attributes[k] != v { | ||
t.Fatalf( | ||
"bad: %s\n\n expected: %#v -> %#v\n got: %#v -> %#v\n in: %#v", | ||
tn, k, v, k, is.Attributes[k], is.Attributes) | ||
} | ||
} | ||
} | ||
} | ||
|
||
func TestConsulKeysMigrateState_empty(t *testing.T) { | ||
var is *terraform.InstanceState | ||
var meta interface{} | ||
|
||
// should handle nil | ||
is, err := resourceConsulKeys().MigrateState(0, is, meta) | ||
|
||
if err != nil { | ||
t.Fatalf("err: %#v", err) | ||
} | ||
if is != nil { | ||
t.Fatalf("expected nil instancestate, got: %#v", is) | ||
} | ||
|
||
// should handle non-nil but empty | ||
is = &terraform.InstanceState{} | ||
is, err = resourceConsulKeys().MigrateState(0, is, meta) | ||
|
||
if err != nil { | ||
t.Fatalf("err: %#v", err) | ||
} | ||
} |
Oops, something went wrong.