terraform: InstanceState.Meta is value type interface{}
This changes the type of values in Meta for InstanceState to `interface{}`. They were `string` before. This will allow richer structures to be persisted to this without flatmapping them (down with flatmap!). The documentation clearly states that only primitives/collections are allowed here. The only thing using this was helper/schema for schema versioning. Appropriate type checking was added to make this change safe. The timeout work @catsby is doing will use this for a richer structure.
This commit is contained in:
parent
9379ec9c60
commit
3342aa580c
|
@ -353,7 +353,7 @@ func (r *Resource) Data(s *terraform.InstanceState) *ResourceData {
|
|||
}
|
||||
|
||||
// Set the schema version to latest by default
|
||||
result.meta = map[string]string{
|
||||
result.meta = map[string]interface{}{
|
||||
"schema_version": strconv.Itoa(r.SchemaVersion),
|
||||
}
|
||||
|
||||
|
@ -378,7 +378,22 @@ func (r *Resource) isTopLevel() bool {
|
|||
// Determines if a given InstanceState needs to be migrated by checking the
|
||||
// stored version number with the current SchemaVersion
|
||||
func (r *Resource) checkSchemaVersion(is *terraform.InstanceState) (bool, int) {
|
||||
stateSchemaVersion, _ := strconv.Atoi(is.Meta["schema_version"])
|
||||
// Get the raw interface{} value for the schema version. If it doesn't
|
||||
// exist or is nil then set it to zero.
|
||||
raw := is.Meta["schema_version"]
|
||||
if raw == nil {
|
||||
raw = "0"
|
||||
}
|
||||
|
||||
// Try to convert it to a string. If it isn't a string then we pretend
|
||||
// that it isn't set at all. It should never not be a string unless it
|
||||
// was manually tampered with.
|
||||
rawString, ok := raw.(string)
|
||||
if !ok {
|
||||
rawString = "0"
|
||||
}
|
||||
|
||||
stateSchemaVersion, _ := strconv.Atoi(rawString)
|
||||
return stateSchemaVersion < r.SchemaVersion, stateSchemaVersion
|
||||
}
|
||||
|
||||
|
@ -386,7 +401,7 @@ func (r *Resource) recordCurrentSchemaVersion(
|
|||
state *terraform.InstanceState) *terraform.InstanceState {
|
||||
if state != nil && r.SchemaVersion > 0 {
|
||||
if state.Meta == nil {
|
||||
state.Meta = make(map[string]string)
|
||||
state.Meta = make(map[string]interface{})
|
||||
}
|
||||
state.Meta["schema_version"] = strconv.Itoa(r.SchemaVersion)
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ type ResourceData struct {
|
|||
config *terraform.ResourceConfig
|
||||
state *terraform.InstanceState
|
||||
diff *terraform.InstanceDiff
|
||||
meta map[string]string
|
||||
meta map[string]interface{}
|
||||
|
||||
// Don't set
|
||||
multiReader *MultiLevelFieldReader
|
||||
|
|
|
@ -52,7 +52,7 @@ func TestResourceApply_create(t *testing.T) {
|
|||
"id": "foo",
|
||||
"foo": "42",
|
||||
},
|
||||
Meta: map[string]string{
|
||||
Meta: map[string]interface{}{
|
||||
"schema_version": "2",
|
||||
},
|
||||
}
|
||||
|
@ -210,7 +210,7 @@ func TestResourceApply_destroyPartial(t *testing.T) {
|
|||
"id": "bar",
|
||||
"foo": "42",
|
||||
},
|
||||
Meta: map[string]string{
|
||||
Meta: map[string]interface{}{
|
||||
"schema_version": "3",
|
||||
},
|
||||
}
|
||||
|
@ -558,7 +558,7 @@ func TestResourceRefresh(t *testing.T) {
|
|||
"id": "bar",
|
||||
"foo": "13",
|
||||
},
|
||||
Meta: map[string]string{
|
||||
Meta: map[string]interface{}{
|
||||
"schema_version": "2",
|
||||
},
|
||||
}
|
||||
|
@ -749,7 +749,7 @@ func TestResourceRefresh_needsMigration(t *testing.T) {
|
|||
Attributes: map[string]string{
|
||||
"oldfoo": "1.2",
|
||||
},
|
||||
Meta: map[string]string{
|
||||
Meta: map[string]interface{}{
|
||||
"schema_version": "1",
|
||||
},
|
||||
}
|
||||
|
@ -765,7 +765,7 @@ func TestResourceRefresh_needsMigration(t *testing.T) {
|
|||
"id": "bar",
|
||||
"newfoo": "13",
|
||||
},
|
||||
Meta: map[string]string{
|
||||
Meta: map[string]interface{}{
|
||||
"schema_version": "2",
|
||||
},
|
||||
}
|
||||
|
@ -803,7 +803,7 @@ func TestResourceRefresh_noMigrationNeeded(t *testing.T) {
|
|||
Attributes: map[string]string{
|
||||
"newfoo": "12",
|
||||
},
|
||||
Meta: map[string]string{
|
||||
Meta: map[string]interface{}{
|
||||
"schema_version": "2",
|
||||
},
|
||||
}
|
||||
|
@ -819,7 +819,7 @@ func TestResourceRefresh_noMigrationNeeded(t *testing.T) {
|
|||
"id": "bar",
|
||||
"newfoo": "13",
|
||||
},
|
||||
Meta: map[string]string{
|
||||
Meta: map[string]interface{}{
|
||||
"schema_version": "2",
|
||||
},
|
||||
}
|
||||
|
@ -871,7 +871,7 @@ func TestResourceRefresh_stateSchemaVersionUnset(t *testing.T) {
|
|||
"id": "bar",
|
||||
"newfoo": "13",
|
||||
},
|
||||
Meta: map[string]string{
|
||||
Meta: map[string]interface{}{
|
||||
"schema_version": "1",
|
||||
},
|
||||
}
|
||||
|
@ -945,7 +945,7 @@ func TestResourceData(t *testing.T) {
|
|||
}
|
||||
|
||||
// Set expectations
|
||||
state.Meta = map[string]string{
|
||||
state.Meta = map[string]interface{}{
|
||||
"schema_version": "2",
|
||||
}
|
||||
|
||||
|
|
|
@ -1541,8 +1541,9 @@ type InstanceState struct {
|
|||
|
||||
// Meta is a simple K/V map that is persisted to the State but otherwise
|
||||
// ignored by Terraform core. It's meant to be used for accounting by
|
||||
// external client code.
|
||||
Meta map[string]string `json:"meta"`
|
||||
// external client code. The value here must only contain Go primitives
|
||||
// and collections.
|
||||
Meta map[string]interface{} `json:"meta"`
|
||||
|
||||
// Tainted is used to mark a resource for recreation.
|
||||
Tainted bool `json:"tainted"`
|
||||
|
@ -1561,7 +1562,7 @@ func (s *InstanceState) init() {
|
|||
s.Attributes = make(map[string]string)
|
||||
}
|
||||
if s.Meta == nil {
|
||||
s.Meta = make(map[string]string)
|
||||
s.Meta = make(map[string]interface{})
|
||||
}
|
||||
s.Ephemeral.init()
|
||||
}
|
||||
|
|
|
@ -278,7 +278,7 @@ func TestStateDeepCopy(t *testing.T) {
|
|||
Resources: map[string]*ResourceState{
|
||||
"test_instance.foo": &ResourceState{
|
||||
Primary: &InstanceState{
|
||||
Meta: map[string]string{},
|
||||
Meta: map[string]interface{}{},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -298,7 +298,7 @@ func TestStateDeepCopy(t *testing.T) {
|
|||
Resources: map[string]*ResourceState{
|
||||
"test_instance.foo": &ResourceState{
|
||||
Primary: &InstanceState{
|
||||
Meta: map[string]string{},
|
||||
Meta: map[string]interface{}{},
|
||||
},
|
||||
Deposed: []*InstanceState{
|
||||
{ID: "test"},
|
||||
|
@ -389,7 +389,7 @@ func TestStateEqual(t *testing.T) {
|
|||
Resources: map[string]*ResourceState{
|
||||
"test_instance.foo": &ResourceState{
|
||||
Primary: &InstanceState{
|
||||
Meta: map[string]string{
|
||||
Meta: map[string]interface{}{
|
||||
"schema_version": "1",
|
||||
},
|
||||
},
|
||||
|
@ -405,7 +405,7 @@ func TestStateEqual(t *testing.T) {
|
|||
Resources: map[string]*ResourceState{
|
||||
"test_instance.foo": &ResourceState{
|
||||
Primary: &InstanceState{
|
||||
Meta: map[string]string{
|
||||
Meta: map[string]interface{}{
|
||||
"schema_version": "2",
|
||||
},
|
||||
},
|
||||
|
@ -610,7 +610,7 @@ func TestStateIncrementSerialMaybe(t *testing.T) {
|
|||
Resources: map[string]*ResourceState{
|
||||
"test_instance.foo": &ResourceState{
|
||||
Primary: &InstanceState{
|
||||
Meta: map[string]string{},
|
||||
Meta: map[string]interface{}{},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -625,7 +625,7 @@ func TestStateIncrementSerialMaybe(t *testing.T) {
|
|||
Resources: map[string]*ResourceState{
|
||||
"test_instance.foo": &ResourceState{
|
||||
Primary: &InstanceState{
|
||||
Meta: map[string]string{
|
||||
Meta: map[string]interface{}{
|
||||
"schema_version": "1",
|
||||
},
|
||||
},
|
||||
|
|
|
@ -150,16 +150,22 @@ func (old *instanceStateV1) upgradeToV2() (*InstanceState, error) {
|
|||
if err != nil {
|
||||
return nil, fmt.Errorf("Error upgrading InstanceState V1: %v", err)
|
||||
}
|
||||
|
||||
meta, err := copystructure.Copy(old.Meta)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error upgrading InstanceState V1: %v", err)
|
||||
}
|
||||
|
||||
newMeta := make(map[string]interface{})
|
||||
for k, v := range meta.(map[string]string) {
|
||||
newMeta[k] = v
|
||||
}
|
||||
|
||||
return &InstanceState{
|
||||
ID: old.ID,
|
||||
Attributes: attributes.(map[string]string),
|
||||
Ephemeral: *ephemeral,
|
||||
Meta: meta.(map[string]string),
|
||||
Meta: newMeta,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue