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
|
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.
|
// Input asks for input to fill variables and provider configurations.
|
||||||
// This modifies the configuration in-place, so asking for Input twice
|
// This modifies the configuration in-place, so asking for Input twice
|
||||||
// may result in different UI output showing different current values.
|
// may result in different UI output showing different current values.
|
||||||
|
|
|
@ -46,6 +46,10 @@ type InterpolationScope struct {
|
||||||
func (i *Interpolater) Values(
|
func (i *Interpolater) Values(
|
||||||
scope *InterpolationScope,
|
scope *InterpolationScope,
|
||||||
vars map[string]config.InterpolatedVariable) (map[string]ast.Variable, error) {
|
vars map[string]config.InterpolatedVariable) (map[string]ast.Variable, error) {
|
||||||
|
if scope == nil {
|
||||||
|
scope = &InterpolationScope{}
|
||||||
|
}
|
||||||
|
|
||||||
result := make(map[string]ast.Variable, len(vars))
|
result := make(map[string]ast.Variable, len(vars))
|
||||||
|
|
||||||
// Copy the default variables
|
// Copy the default variables
|
||||||
|
@ -369,7 +373,12 @@ func (i *Interpolater) computeResourceVariable(
|
||||||
// If we're requesting "count" its a special variable that we grab
|
// If we're requesting "count" its a special variable that we grab
|
||||||
// directly from the config itself.
|
// directly from the config itself.
|
||||||
if v.Field == "count" {
|
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 {
|
if err != nil {
|
||||||
return nil, fmt.Errorf(
|
return nil, fmt.Errorf(
|
||||||
"Error reading %s count: %s",
|
"Error reading %s count: %s",
|
||||||
|
@ -380,26 +389,36 @@ func (i *Interpolater) computeResourceVariable(
|
||||||
return &ast.Variable{Type: ast.TypeInt, Value: count}, nil
|
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
|
// 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
|
// at this point and if there is a state, we expect there to be a
|
||||||
// resource with the given name.
|
// resource with the given name.
|
||||||
r, ok := module.Resources[id]
|
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 {
|
if !ok && v.Multi && v.Index == 0 {
|
||||||
r, ok = module.Resources[v.ResourceId()]
|
r, ok = module.Resources[v.ResourceId()]
|
||||||
}
|
}
|
||||||
if !ok {
|
if !ok {
|
||||||
r = nil
|
r = nil
|
||||||
}
|
}
|
||||||
if r == nil {
|
}
|
||||||
goto MISSING
|
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
|
goto MISSING
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -672,12 +691,6 @@ func (i *Interpolater) resourceVariableInfo(
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if cr == nil {
|
|
||||||
return nil, nil, fmt.Errorf(
|
|
||||||
"Resource '%s' not found for variable '%s'",
|
|
||||||
v.ResourceId(),
|
|
||||||
v.FullKey())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the relevant module
|
// Get the relevant module
|
||||||
module := i.State.ModuleByPath(scope.Path)
|
module := i.State.ModuleByPath(scope.Path)
|
||||||
|
|
Loading…
Reference in New Issue