helper/schema: support for NewRemoved

This commit is contained in:
Mitchell Hashimoto 2014-08-18 15:07:09 -07:00
parent ce42845acd
commit 4ae1673580
4 changed files with 150 additions and 37 deletions

View File

@ -135,53 +135,49 @@ func (d *ResourceData) getMap(
source getSource) interface{} {
elemSchema := &Schema{Type: TypeString}
// Get the full map
var result map[string]interface{}
result := make(map[string]interface{})
prefix := k + "."
// Try set first
if d.setMap != nil && source >= getSourceSet {
for k, _ := range d.setMap {
if !strings.HasPrefix(k, prefix) {
continue
}
single := k[len(prefix):]
if result == nil {
result = make(map[string]interface{})
}
result[single] = d.getPrimitive(k, nil, elemSchema, source)
}
}
if result == nil && d.diff != nil && source >= getSourceDiff {
for k, _ := range d.diff.Attributes {
if !strings.HasPrefix(k, prefix) {
continue
}
single := k[len(prefix):]
if result == nil {
result = make(map[string]interface{})
}
result[single] = d.getPrimitive(k, nil, elemSchema, source)
}
}
if result == nil && d.state != nil && source >= getSourceState {
if d.state != nil && source >= getSourceState {
for k, _ := range d.state.Attributes {
if !strings.HasPrefix(k, prefix) {
continue
}
single := k[len(prefix):]
if result == nil {
result = make(map[string]interface{})
result[single] = d.getPrimitive(k, nil, elemSchema, source)
}
}
if d.diff != nil && source >= getSourceDiff {
for k, v := range d.diff.Attributes {
if !strings.HasPrefix(k, prefix) {
continue
}
single := k[len(prefix):]
if v.NewRemoved {
delete(result, single)
} else {
result[single] = d.getPrimitive(k, nil, elemSchema, source)
}
}
}
if d.setMap != nil && source >= getSourceSet {
cleared := false
for k, _ := range d.setMap {
if !strings.HasPrefix(k, prefix) {
continue
}
if !cleared {
// We clear the results if they are in the set map
result = make(map[string]interface{})
cleared = true
}
single := k[len(prefix):]
result[single] = d.getPrimitive(k, nil, elemSchema, source)
}
}
@ -390,6 +386,14 @@ func (d *ResourceData) setMapValue(
return fmt.Errorf("%s: full map must be set, no a single element", k)
}
// Delete any prior map set
/*
v := d.getMap(k, nil, schema, getSourceSet)
for subKey, _ := range v.(map[string]interface{}) {
delete(d.setMap, fmt.Sprintf("%s.%s", k, subKey))
}
*/
vs := value.(map[string]interface{})
for subKey, v := range vs {
err := d.set(fmt.Sprintf("%s.%s", k, subKey), nil, elemSchema, v)

View File

@ -1078,10 +1078,19 @@ func TestResourceDataState(t *testing.T) {
Attributes: map[string]string{
"config_vars.#": "2",
"config_vars.0.foo": "bar",
"config_vars.0.bar": "bar",
"config_vars.1.bar": "baz",
},
},
Diff: &terraform.ResourceDiff{
Attributes: map[string]*terraform.ResourceAttrDiff{
"config_vars.0.bar": &terraform.ResourceAttrDiff{
NewRemoved: true,
},
},
},
Set: map[string]interface{}{
"config_vars.1": map[string]interface{}{
"baz": "bang",

View File

@ -198,6 +198,8 @@ func (m schemaMap) diff(
err = m.diffString(k, schema, diff, s, c)
case TypeList:
err = m.diffList(k, schema, diff, s, c)
case TypeMap:
err = m.diffMap(k, schema, diff, s, c)
default:
err = fmt.Errorf("%s: unknown type %s", k, schema.Type)
}
@ -281,6 +283,61 @@ func (m schemaMap) diffList(
return nil
}
func (m schemaMap) diffMap(
k string,
schema *Schema,
diff *terraform.ResourceDiff,
s *terraform.ResourceState,
c *terraform.ResourceConfig) error {
//elemSchema := &Schema{Type: TypeString}
prefix := k + "."
// First get all the values from the state
stateMap := make(map[string]string)
if s != nil {
for sk, sv := range s.Attributes {
if !strings.HasPrefix(sk, prefix) {
continue
}
stateMap[sk[len(prefix):]] = sv
}
}
// Then get all the values from the configuration
configMap := make(map[string]string)
if c != nil {
if raw, ok := c.Get(k); ok {
for k, v := range raw.(map[string]interface{}) {
configMap[k] = v.(string)
}
}
}
// Now we compare, preferring values from the config map
for k, v := range configMap {
old := stateMap[k]
delete(stateMap, k)
if old == v {
continue
}
diff.Attributes[prefix+k] = schema.finalizeDiff(&terraform.ResourceAttrDiff{
Old: old,
New: v,
})
}
for k, v := range stateMap {
diff.Attributes[prefix+k] = schema.finalizeDiff(&terraform.ResourceAttrDiff{
Old: v,
NewRemoved: true,
})
}
return nil
}
func (m schemaMap) diffString(
k string,
schema *Schema,

View File

@ -548,6 +548,49 @@ func TestSchemaMap_Diff(t *testing.T) {
Err: false,
},
*/
/*
* Maps
*/
{
Schema: map[string]*Schema{
"config_vars": &Schema{
Type: TypeList,
Elem: &Schema{Type: TypeMap},
},
},
State: &terraform.ResourceState{
Attributes: map[string]string{
"config_vars.#": "1",
"config_vars.0.foo": "bar",
},
},
Config: map[string]interface{}{
"config_vars": []interface{}{
map[string]interface{}{
"bar": "baz",
},
},
},
Diff: &terraform.ResourceDiff{
Attributes: map[string]*terraform.ResourceAttrDiff{
"config_vars.0.foo": &terraform.ResourceAttrDiff{
Old: "bar",
NewRemoved: true,
},
"config_vars.0.bar": &terraform.ResourceAttrDiff{
Old: "",
New: "baz",
},
},
},
Err: false,
},
}
for i, tc := range cases {