terraform: update interpolation to be more flexible w/o config
This commit is contained in:
parent
73a1564dac
commit
1a8fbdc428
|
@ -229,6 +229,21 @@ func (c *Context) ShadowError() error {
|
|||
return c.shadowErr
|
||||
}
|
||||
|
||||
// Interpolater returns an Interpolater built on a copy of the state
|
||||
// that can be used to test interpolation values.
|
||||
func (c *Context) Interpolater() *Interpolater {
|
||||
var varLock sync.Mutex
|
||||
var stateLock sync.RWMutex
|
||||
return &Interpolater{
|
||||
Operation: walkApply,
|
||||
Module: c.module,
|
||||
State: c.state.DeepCopy(),
|
||||
StateLock: &stateLock,
|
||||
VariableValues: map[string]interface{}{},
|
||||
VariableValuesLock: &varLock,
|
||||
}
|
||||
}
|
||||
|
||||
// Input asks for input to fill variables and provider configurations.
|
||||
// This modifies the configuration in-place, so asking for Input twice
|
||||
// may result in different UI output showing different current values.
|
||||
|
|
|
@ -46,6 +46,10 @@ type InterpolationScope struct {
|
|||
func (i *Interpolater) Values(
|
||||
scope *InterpolationScope,
|
||||
vars map[string]config.InterpolatedVariable) (map[string]ast.Variable, error) {
|
||||
if scope == nil {
|
||||
scope = &InterpolationScope{}
|
||||
}
|
||||
|
||||
result := make(map[string]ast.Variable, len(vars))
|
||||
|
||||
// Copy the default variables
|
||||
|
@ -369,7 +373,12 @@ func (i *Interpolater) computeResourceVariable(
|
|||
// If we're requesting "count" its a special variable that we grab
|
||||
// directly from the config itself.
|
||||
if v.Field == "count" {
|
||||
count, err := cr.Count()
|
||||
var count int
|
||||
if cr != nil {
|
||||
count, err = cr.Count()
|
||||
} else {
|
||||
count, err = i.resourceCountMax(module, cr, v)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(
|
||||
"Error reading %s count: %s",
|
||||
|
@ -380,26 +389,36 @@ func (i *Interpolater) computeResourceVariable(
|
|||
return &ast.Variable{Type: ast.TypeInt, Value: count}, nil
|
||||
}
|
||||
|
||||
// If we have no module in the state yet or count, return empty
|
||||
if module == nil || len(module.Resources) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Get the resource out from the state. We know the state exists
|
||||
// at this point and if there is a state, we expect there to be a
|
||||
// resource with the given name.
|
||||
r, ok := module.Resources[id]
|
||||
if !ok && v.Multi && v.Index == 0 {
|
||||
r, ok = module.Resources[v.ResourceId()]
|
||||
}
|
||||
if !ok {
|
||||
r = nil
|
||||
}
|
||||
if r == nil {
|
||||
goto MISSING
|
||||
var r *ResourceState
|
||||
if module != nil && len(module.Resources) > 0 {
|
||||
var ok bool
|
||||
r, ok = module.Resources[id]
|
||||
if !ok && v.Multi && v.Index == 0 {
|
||||
r, ok = module.Resources[v.ResourceId()]
|
||||
}
|
||||
if !ok {
|
||||
r = nil
|
||||
}
|
||||
}
|
||||
if r == nil || r.Primary == nil {
|
||||
if i.Operation == walkApply || i.Operation == walkPlan {
|
||||
return nil, fmt.Errorf(
|
||||
"Resource '%s' not found for variable '%s'",
|
||||
v.ResourceId(),
|
||||
v.FullKey())
|
||||
}
|
||||
|
||||
// If we have no module in the state yet or count, return empty.
|
||||
// NOTE(@mitchellh): I actually don't know why this is here. During
|
||||
// a refactor I kept this here to maintain the same behavior, but
|
||||
// I'm not sure why its here.
|
||||
if module == nil || len(module.Resources) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if r.Primary == nil {
|
||||
goto MISSING
|
||||
}
|
||||
|
||||
|
@ -672,12 +691,6 @@ func (i *Interpolater) resourceVariableInfo(
|
|||
break
|
||||
}
|
||||
}
|
||||
if cr == nil {
|
||||
return nil, nil, fmt.Errorf(
|
||||
"Resource '%s' not found for variable '%s'",
|
||||
v.ResourceId(),
|
||||
v.FullKey())
|
||||
}
|
||||
|
||||
// Get the relevant module
|
||||
module := i.State.ModuleByPath(scope.Path)
|
||||
|
|
Loading…
Reference in New Issue