terraform: support data source apply for shadows

This commit is contained in:
Mitchell Hashimoto 2016-10-12 18:56:57 +08:00
parent 4c951428d7
commit 98fa7d92a4
No known key found for this signature in database
GPG Key ID: 744E147AA52F5B0A
2 changed files with 74 additions and 6 deletions

View File

@ -400,6 +400,21 @@ func (d *InstanceDiff) Empty() bool {
return !d.Destroy && !d.DestroyTainted && len(d.Attributes) == 0 return !d.Destroy && !d.DestroyTainted && len(d.Attributes) == 0
} }
// Equal compares two diffs for exact equality.
//
// This is different from the Same comparison that is supported which
// checks for operation equality taking into account computed values. Equal
// instead checks for exact equality.
func (d *InstanceDiff) Equal(d2 *InstanceDiff) bool {
// If one is nil, they must both be nil
if d == nil || d2 == nil {
return d == d2
}
// Use DeepEqual
return reflect.DeepEqual(d, d2)
}
// DeepCopy performs a deep copy of all parts of the InstanceDiff // DeepCopy performs a deep copy of all parts of the InstanceDiff
func (d *InstanceDiff) DeepCopy() *InstanceDiff { func (d *InstanceDiff) DeepCopy() *InstanceDiff {
copy, err := copystructure.Config{Lock: true}.Copy(d) copy, err := copystructure.Config{Lock: true}.Copy(d)

View File

@ -254,6 +254,22 @@ func (p *shadowResourceProviderReal) ReadDataDiff(
return result, err return result, err
} }
func (p *shadowResourceProviderReal) ReadDataApply(
info *InstanceInfo,
diff *InstanceDiff) (*InstanceState, error) {
// Thse have to be copied before the call since call can modify
diffCopy := diff.DeepCopy()
result, err := p.ResourceProvider.ReadDataApply(info, diff)
p.Shared.ReadDataApply.SetValue(info.uniqueId(), &shadowResourceProviderReadDataApply{
Diff: diffCopy,
Result: result.DeepCopy(),
ResultErr: err,
})
return result, err
}
// shadowResourceProviderShadow is the shadow resource provider. Function // shadowResourceProviderShadow is the shadow resource provider. Function
// calls never affect real resources. This is paired with the "real" side // calls never affect real resources. This is paired with the "real" side
// which must be called properly to enable recording. // which must be called properly to enable recording.
@ -282,6 +298,7 @@ type shadowResourceProviderShared struct {
Refresh shadow.KeyedValue Refresh shadow.KeyedValue
ValidateDataSource shadow.KeyedValue ValidateDataSource shadow.KeyedValue
ReadDataDiff shadow.KeyedValue ReadDataDiff shadow.KeyedValue
ReadDataApply shadow.KeyedValue
} }
func (p *shadowResourceProviderShared) Close() error { func (p *shadowResourceProviderShared) Close() error {
@ -679,6 +696,42 @@ func (p *shadowResourceProviderShadow) ReadDataDiff(
return result.Result, result.ResultErr return result.Result, result.ResultErr
} }
func (p *shadowResourceProviderShadow) ReadDataApply(
info *InstanceInfo,
d *InstanceDiff) (*InstanceState, error) {
// Unique key
key := info.uniqueId()
raw := p.Shared.ReadDataApply.Value(key)
if raw == nil {
p.ErrorLock.Lock()
defer p.ErrorLock.Unlock()
p.Error = multierror.Append(p.Error, fmt.Errorf(
"Unknown 'ReadDataApply' call for %q:\n\n%#v",
key, d))
return nil, nil
}
result, ok := raw.(*shadowResourceProviderReadDataApply)
if !ok {
p.ErrorLock.Lock()
defer p.ErrorLock.Unlock()
p.Error = multierror.Append(p.Error, fmt.Errorf(
"Unknown 'ReadDataApply' shadow value: %#v", raw))
return nil, nil
}
// Compare the parameters, which should be identical
if !d.Equal(result.Diff) {
p.ErrorLock.Lock()
p.Error = multierror.Append(p.Error, fmt.Errorf(
"ReadDataApply: unequal diffs (real, then shadow):\n\n%#v\n\n%#v",
result.Diff, d))
p.ErrorLock.Unlock()
}
return result.Result, result.ResultErr
}
// TODO // TODO
// TODO // TODO
// TODO // TODO
@ -689,12 +742,6 @@ func (p *shadowResourceProviderShadow) ImportState(info *InstanceInfo, id string
return nil, nil return nil, nil
} }
func (p *shadowResourceProviderShadow) ReadDataApply(
info *InstanceInfo,
d *InstanceDiff) (*InstanceState, error) {
return nil, nil
}
// The structs for the various function calls are put below. These structs // The structs for the various function calls are put below. These structs
// are used to carry call information across the real/shadow boundaries. // are used to carry call information across the real/shadow boundaries.
@ -764,3 +811,9 @@ type shadowResourceProviderReadDataDiff struct {
Result *InstanceDiff Result *InstanceDiff
ResultErr error ResultErr error
} }
type shadowResourceProviderReadDataApply struct {
Diff *InstanceDiff
Result *InstanceState
ResultErr error
}