helper/diff: calculate removed keys
This commit is contained in:
parent
fdfed5000f
commit
2d97738636
|
@ -55,45 +55,70 @@ func (b *ResourceBuilder) Diff(
|
||||||
flatRaw := flatmap.Flatten(c.Raw)
|
flatRaw := flatmap.Flatten(c.Raw)
|
||||||
flatConfig := flatmap.Flatten(c.Config)
|
flatConfig := flatmap.Flatten(c.Config)
|
||||||
|
|
||||||
for k, v := range flatRaw {
|
for ak, at := range b.Attrs {
|
||||||
// Make sure this is an attribute that actually affects
|
// Keep track of all the keys we saw in the raw structure
|
||||||
// the diff in some way.
|
// so that we can prune our attributes later.
|
||||||
var attr AttrType
|
seenKeys := make([]string, 0)
|
||||||
for ak, at := range b.Attrs {
|
|
||||||
if strings.HasPrefix(k, ak) {
|
// Go through and find the added/changed keys in flatRaw
|
||||||
attr = at
|
for k, v := range flatRaw {
|
||||||
break
|
// Find only the attributes that match our prefix
|
||||||
|
if !strings.HasPrefix(k, ak) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Track that we saw this key
|
||||||
|
seenKeys = append(seenKeys, k)
|
||||||
|
|
||||||
|
// If this key is in the cleaned config, then use that value
|
||||||
|
// because it'll have its variables properly interpolated
|
||||||
|
if cleanV, ok := flatConfig[k]; ok {
|
||||||
|
v = cleanV
|
||||||
|
}
|
||||||
|
|
||||||
|
oldV, ok := s.Attributes[k]
|
||||||
|
|
||||||
|
// If there is an old value and they're the same, no change
|
||||||
|
if ok && oldV == v {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Record the change
|
||||||
|
attrs[k] = &terraform.ResourceAttrDiff{
|
||||||
|
Old: oldV,
|
||||||
|
New: v,
|
||||||
|
Type: terraform.DiffAttrInput,
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this requires a new resource, record that and flag our
|
||||||
|
// boolean.
|
||||||
|
if at == AttrTypeCreate {
|
||||||
|
attrs[k].RequiresNew = true
|
||||||
|
requiresNew = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if attr == AttrTypeUnknown {
|
|
||||||
continue
|
// Go through our attribues and find the deleted keys
|
||||||
|
matchingKeys := make(map[string]struct{})
|
||||||
|
for k, _ := range s.Attributes {
|
||||||
|
// Find only the attributes that match our prefix
|
||||||
|
if !strings.HasPrefix(k, ak) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
matchingKeys[k] = struct{}{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this key is in the cleaned config, then use that value
|
// Delete the keys we saw to find the deleted keys
|
||||||
// because it'll have its variables properly interpolated
|
for _, k := range seenKeys {
|
||||||
if cleanV, ok := flatConfig[k]; ok {
|
delete(matchingKeys, k)
|
||||||
v = cleanV
|
|
||||||
}
|
}
|
||||||
|
for k, _ := range matchingKeys {
|
||||||
oldV, ok := s.Attributes[k]
|
attrs[k] = &terraform.ResourceAttrDiff{
|
||||||
|
Old: s.Attributes[k],
|
||||||
// If there is an old value and they're the same, no change
|
New: "",
|
||||||
if ok && oldV == v {
|
Type: terraform.DiffAttrInput,
|
||||||
continue
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Record the change
|
|
||||||
attrs[k] = &terraform.ResourceAttrDiff{
|
|
||||||
Old: oldV,
|
|
||||||
New: v,
|
|
||||||
Type: terraform.DiffAttrInput,
|
|
||||||
}
|
|
||||||
|
|
||||||
// If this requires a new resource, record that and flag our
|
|
||||||
// boolean.
|
|
||||||
if attr == AttrTypeCreate {
|
|
||||||
attrs[k].RequiresNew = true
|
|
||||||
requiresNew = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,45 @@ func TestResourceBuilder_complex(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestResourceBuilder_complexReplace(t *testing.T) {
|
||||||
|
rb := &ResourceBuilder{
|
||||||
|
Attrs: map[string]AttrType{
|
||||||
|
"listener": AttrTypeUpdate,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
state := &terraform.ResourceState{
|
||||||
|
ID: "foo",
|
||||||
|
Attributes: map[string]string{
|
||||||
|
"ignore": "1",
|
||||||
|
"listener.#": "1",
|
||||||
|
"listener.0.port": "80",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
c := testConfig(t, map[string]interface{}{
|
||||||
|
"listener": []interface{}{
|
||||||
|
map[interface{}]interface{}{
|
||||||
|
"value": "50",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, nil)
|
||||||
|
|
||||||
|
diff, err := rb.Diff(state, c)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
if diff == nil {
|
||||||
|
t.Fatal("should not be nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
actual := testResourceDiffStr(diff)
|
||||||
|
expected := testRBComplexReplaceDiff
|
||||||
|
if actual != expected {
|
||||||
|
t.Fatalf("bad: %s", actual)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestResourceBuilder_new(t *testing.T) {
|
func TestResourceBuilder_new(t *testing.T) {
|
||||||
rb := &ResourceBuilder{
|
rb := &ResourceBuilder{
|
||||||
Attrs: map[string]AttrType{
|
Attrs: map[string]AttrType{
|
||||||
|
@ -200,6 +239,11 @@ const testRBComplexDiff = `UPDATE
|
||||||
IN listener.0.port: "80" => "3000"
|
IN listener.0.port: "80" => "3000"
|
||||||
`
|
`
|
||||||
|
|
||||||
|
const testRBComplexReplaceDiff = `UPDATE
|
||||||
|
IN listener.0.port: "80" => ""
|
||||||
|
IN listener.0.value: "" => "50"
|
||||||
|
`
|
||||||
|
|
||||||
const testRBNewDiff = `UPDATE
|
const testRBNewDiff = `UPDATE
|
||||||
IN foo: "" => "bar"
|
IN foo: "" => "bar"
|
||||||
OUT private_ip: "" => "<computed>"
|
OUT private_ip: "" => "<computed>"
|
||||||
|
|
Loading…
Reference in New Issue