github.com/skyscape-cloud-services/terraform@v0.9.2-0.20170609144644-7ece028a1747/terraform/eval_count.go (about)

     1  package terraform
     2  
     3  import (
     4  	"github.com/hashicorp/terraform/config"
     5  )
     6  
     7  // EvalCountFixZeroOneBoundary is an EvalNode that fixes up the state
     8  // when there is a resource count with zero/one boundary, i.e. fixing
     9  // a resource named "aws_instance.foo" to "aws_instance.foo.0" and vice-versa.
    10  type EvalCountFixZeroOneBoundary struct {
    11  	Resource *config.Resource
    12  }
    13  
    14  // TODO: test
    15  func (n *EvalCountFixZeroOneBoundary) Eval(ctx EvalContext) (interface{}, error) {
    16  	// Get the count, important for knowing whether we're supposed to
    17  	// be adding the zero, or trimming it.
    18  	count, err := n.Resource.Count()
    19  	if err != nil {
    20  		return nil, err
    21  	}
    22  
    23  	// Figure what to look for and what to replace it with
    24  	hunt := n.Resource.Id()
    25  	replace := hunt + ".0"
    26  	if count < 2 {
    27  		hunt, replace = replace, hunt
    28  	}
    29  
    30  	state, lock := ctx.State()
    31  
    32  	// Get a lock so we can access this instance and potentially make
    33  	// changes to it.
    34  	lock.Lock()
    35  	defer lock.Unlock()
    36  
    37  	// Look for the module state. If we don't have one, then it doesn't matter.
    38  	mod := state.ModuleByPath(ctx.Path())
    39  	if mod == nil {
    40  		return nil, nil
    41  	}
    42  
    43  	// Look for the resource state. If we don't have one, then it is okay.
    44  	rs, ok := mod.Resources[hunt]
    45  	if !ok {
    46  		return nil, nil
    47  	}
    48  
    49  	// If the replacement key exists, we just keep both
    50  	if _, ok := mod.Resources[replace]; ok {
    51  		return nil, nil
    52  	}
    53  
    54  	mod.Resources[replace] = rs
    55  	delete(mod.Resources, hunt)
    56  
    57  	return nil, nil
    58  }