github.com/anfernee/terraform@v0.6.16-0.20160430000239-06e5085a92f2/terraform/state.go (about)

     1  package terraform
     2  
     3  import (
     4  	"bufio"
     5  	"bytes"
     6  	"encoding/json"
     7  	"fmt"
     8  	"io"
     9  	"log"
    10  	"reflect"
    11  	"sort"
    12  	"strconv"
    13  	"strings"
    14  
    15  	"github.com/hashicorp/terraform/config"
    16  )
    17  
    18  const (
    19  	// StateVersion is the current version for our state file
    20  	StateVersion = 1
    21  )
    22  
    23  // rootModulePath is the path of the root module
    24  var rootModulePath = []string{"root"}
    25  
    26  // State keeps track of a snapshot state-of-the-world that Terraform
    27  // can use to keep track of what real world resources it is actually
    28  // managing. This is the latest format as of Terraform 0.3
    29  type State struct {
    30  	// Version is the protocol version. Currently only "1".
    31  	Version int `json:"version"`
    32  
    33  	// Serial is incremented on any operation that modifies
    34  	// the State file. It is used to detect potentially conflicting
    35  	// updates.
    36  	Serial int64 `json:"serial"`
    37  
    38  	// Remote is used to track the metadata required to
    39  	// pull and push state files from a remote storage endpoint.
    40  	Remote *RemoteState `json:"remote,omitempty"`
    41  
    42  	// Modules contains all the modules in a breadth-first order
    43  	Modules []*ModuleState `json:"modules"`
    44  }
    45  
    46  // NewState is used to initialize a blank state
    47  func NewState() *State {
    48  	s := &State{}
    49  	s.init()
    50  	return s
    51  }
    52  
    53  // Children returns the ModuleStates that are direct children of
    54  // the given path. If the path is "root", for example, then children
    55  // returned might be "root.child", but not "root.child.grandchild".
    56  func (s *State) Children(path []string) []*ModuleState {
    57  	// TODO: test
    58  
    59  	result := make([]*ModuleState, 0)
    60  	for _, m := range s.Modules {
    61  		if len(m.Path) != len(path)+1 {
    62  			continue
    63  		}
    64  		if !reflect.DeepEqual(path, m.Path[:len(path)]) {
    65  			continue
    66  		}
    67  
    68  		result = append(result, m)
    69  	}
    70  
    71  	return result
    72  }
    73  
    74  // AddModule adds the module with the given path to the state.
    75  //
    76  // This should be the preferred method to add module states since it
    77  // allows us to optimize lookups later as well as control sorting.
    78  func (s *State) AddModule(path []string) *ModuleState {
    79  	m := &ModuleState{Path: path}
    80  	m.init()
    81  	s.Modules = append(s.Modules, m)
    82  	s.sort()
    83  	return m
    84  }
    85  
    86  // ModuleByPath is used to lookup the module state for the given path.
    87  // This should be the preferred lookup mechanism as it allows for future
    88  // lookup optimizations.
    89  func (s *State) ModuleByPath(path []string) *ModuleState {
    90  	if s == nil {
    91  		return nil
    92  	}
    93  	for _, mod := range s.Modules {
    94  		if mod.Path == nil {
    95  			panic("missing module path")
    96  		}
    97  		if reflect.DeepEqual(mod.Path, path) {
    98  			return mod
    99  		}
   100  	}
   101  	return nil
   102  }
   103  
   104  // ModuleOrphans returns all the module orphans in this state by
   105  // returning their full paths. These paths can be used with ModuleByPath
   106  // to return the actual state.
   107  func (s *State) ModuleOrphans(path []string, c *config.Config) [][]string {
   108  	// direct keeps track of what direct children we have both in our config
   109  	// and in our state. childrenKeys keeps track of what isn't an orphan.
   110  	direct := make(map[string]struct{})
   111  	childrenKeys := make(map[string]struct{})
   112  	if c != nil {
   113  		for _, m := range c.Modules {
   114  			childrenKeys[m.Name] = struct{}{}
   115  			direct[m.Name] = struct{}{}
   116  		}
   117  	}
   118  
   119  	// Go over the direct children and find any that aren't in our keys.
   120  	var orphans [][]string
   121  	for _, m := range s.Children(path) {
   122  		key := m.Path[len(m.Path)-1]
   123  
   124  		// Record that we found this key as a direct child. We use this
   125  		// later to find orphan nested modules.
   126  		direct[key] = struct{}{}
   127  
   128  		// If we have a direct child still in our config, it is not an orphan
   129  		if _, ok := childrenKeys[key]; ok {
   130  			continue
   131  		}
   132  
   133  		orphans = append(orphans, m.Path)
   134  	}
   135  
   136  	// Find the orphans that are nested...
   137  	for _, m := range s.Modules {
   138  		// We only want modules that are at least grandchildren
   139  		if len(m.Path) < len(path)+2 {
   140  			continue
   141  		}
   142  
   143  		// If it isn't part of our tree, continue
   144  		if !reflect.DeepEqual(path, m.Path[:len(path)]) {
   145  			continue
   146  		}
   147  
   148  		// If we have the direct child, then just skip it.
   149  		key := m.Path[len(path)]
   150  		if _, ok := direct[key]; ok {
   151  			continue
   152  		}
   153  
   154  		orphanPath := m.Path[:len(path)+1]
   155  
   156  		// Don't double-add if we've already added this orphan (which can happen if
   157  		// there are multiple nested sub-modules that get orphaned together).
   158  		alreadyAdded := false
   159  		for _, o := range orphans {
   160  			if reflect.DeepEqual(o, orphanPath) {
   161  				alreadyAdded = true
   162  				break
   163  			}
   164  		}
   165  		if alreadyAdded {
   166  			continue
   167  		}
   168  
   169  		// Add this orphan
   170  		orphans = append(orphans, orphanPath)
   171  	}
   172  
   173  	return orphans
   174  }
   175  
   176  // Empty returns true if the state is empty.
   177  func (s *State) Empty() bool {
   178  	if s == nil {
   179  		return true
   180  	}
   181  
   182  	return len(s.Modules) == 0
   183  }
   184  
   185  // IsRemote returns true if State represents a state that exists and is
   186  // remote.
   187  func (s *State) IsRemote() bool {
   188  	if s == nil {
   189  		return false
   190  	}
   191  	if s.Remote == nil {
   192  		return false
   193  	}
   194  	if s.Remote.Type == "" {
   195  		return false
   196  	}
   197  
   198  	return true
   199  }
   200  
   201  // RootModule returns the ModuleState for the root module
   202  func (s *State) RootModule() *ModuleState {
   203  	root := s.ModuleByPath(rootModulePath)
   204  	if root == nil {
   205  		panic("missing root module")
   206  	}
   207  	return root
   208  }
   209  
   210  // Equal tests if one state is equal to another.
   211  func (s *State) Equal(other *State) bool {
   212  	// If one is nil, we do a direct check
   213  	if s == nil || other == nil {
   214  		return s == other
   215  	}
   216  
   217  	// If the versions are different, they're certainly not equal
   218  	if s.Version != other.Version {
   219  		return false
   220  	}
   221  
   222  	// If any of the modules are not equal, then this state isn't equal
   223  	if len(s.Modules) != len(other.Modules) {
   224  		return false
   225  	}
   226  	for _, m := range s.Modules {
   227  		// This isn't very optimal currently but works.
   228  		otherM := other.ModuleByPath(m.Path)
   229  		if otherM == nil {
   230  			return false
   231  		}
   232  
   233  		// If they're not equal, then we're not equal!
   234  		if !m.Equal(otherM) {
   235  			return false
   236  		}
   237  	}
   238  
   239  	return true
   240  }
   241  
   242  // DeepCopy performs a deep copy of the state structure and returns
   243  // a new structure.
   244  func (s *State) DeepCopy() *State {
   245  	if s == nil {
   246  		return nil
   247  	}
   248  	n := &State{
   249  		Version: s.Version,
   250  		Serial:  s.Serial,
   251  		Modules: make([]*ModuleState, 0, len(s.Modules)),
   252  	}
   253  	for _, mod := range s.Modules {
   254  		n.Modules = append(n.Modules, mod.deepcopy())
   255  	}
   256  	if s.Remote != nil {
   257  		n.Remote = s.Remote.deepcopy()
   258  	}
   259  	return n
   260  }
   261  
   262  // IncrementSerialMaybe increments the serial number of this state
   263  // if it different from the other state.
   264  func (s *State) IncrementSerialMaybe(other *State) {
   265  	if s == nil {
   266  		return
   267  	}
   268  	if other == nil {
   269  		return
   270  	}
   271  	if s.Serial > other.Serial {
   272  		return
   273  	}
   274  	if !s.Equal(other) {
   275  		if other.Serial > s.Serial {
   276  			s.Serial = other.Serial
   277  		}
   278  
   279  		s.Serial++
   280  	}
   281  }
   282  
   283  func (s *State) init() {
   284  	if s.Version == 0 {
   285  		s.Version = StateVersion
   286  	}
   287  	if len(s.Modules) == 0 {
   288  		root := &ModuleState{
   289  			Path: rootModulePath,
   290  		}
   291  		root.init()
   292  		s.Modules = []*ModuleState{root}
   293  	}
   294  }
   295  
   296  // prune is used to remove any resources that are no longer required
   297  func (s *State) prune() {
   298  	if s == nil {
   299  		return
   300  	}
   301  	for _, mod := range s.Modules {
   302  		mod.prune()
   303  	}
   304  	if s.Remote != nil && s.Remote.Empty() {
   305  		s.Remote = nil
   306  	}
   307  }
   308  
   309  // sort sorts the modules
   310  func (s *State) sort() {
   311  	sort.Sort(moduleStateSort(s.Modules))
   312  
   313  	// Allow modules to be sorted
   314  	for _, m := range s.Modules {
   315  		m.sort()
   316  	}
   317  }
   318  
   319  func (s *State) GoString() string {
   320  	return fmt.Sprintf("*%#v", *s)
   321  }
   322  
   323  func (s *State) String() string {
   324  	if s == nil {
   325  		return "<nil>"
   326  	}
   327  
   328  	var buf bytes.Buffer
   329  	for _, m := range s.Modules {
   330  		mStr := m.String()
   331  
   332  		// If we're the root module, we just write the output directly.
   333  		if reflect.DeepEqual(m.Path, rootModulePath) {
   334  			buf.WriteString(mStr + "\n")
   335  			continue
   336  		}
   337  
   338  		buf.WriteString(fmt.Sprintf("module.%s:\n", strings.Join(m.Path[1:], ".")))
   339  
   340  		s := bufio.NewScanner(strings.NewReader(mStr))
   341  		for s.Scan() {
   342  			text := s.Text()
   343  			if text != "" {
   344  				text = "  " + text
   345  			}
   346  
   347  			buf.WriteString(fmt.Sprintf("%s\n", text))
   348  		}
   349  	}
   350  
   351  	return strings.TrimSpace(buf.String())
   352  }
   353  
   354  // RemoteState is used to track the information about a remote
   355  // state store that we push/pull state to.
   356  type RemoteState struct {
   357  	// Type controls the client we use for the remote state
   358  	Type string `json:"type"`
   359  
   360  	// Config is used to store arbitrary configuration that
   361  	// is type specific
   362  	Config map[string]string `json:"config"`
   363  }
   364  
   365  func (r *RemoteState) deepcopy() *RemoteState {
   366  	confCopy := make(map[string]string, len(r.Config))
   367  	for k, v := range r.Config {
   368  		confCopy[k] = v
   369  	}
   370  	return &RemoteState{
   371  		Type:   r.Type,
   372  		Config: confCopy,
   373  	}
   374  }
   375  
   376  func (r *RemoteState) Empty() bool {
   377  	return r == nil || r.Type == ""
   378  }
   379  
   380  func (r *RemoteState) Equals(other *RemoteState) bool {
   381  	if r.Type != other.Type {
   382  		return false
   383  	}
   384  	if len(r.Config) != len(other.Config) {
   385  		return false
   386  	}
   387  	for k, v := range r.Config {
   388  		if other.Config[k] != v {
   389  			return false
   390  		}
   391  	}
   392  	return true
   393  }
   394  
   395  func (r *RemoteState) GoString() string {
   396  	return fmt.Sprintf("*%#v", *r)
   397  }
   398  
   399  // ModuleState is used to track all the state relevant to a single
   400  // module. Previous to Terraform 0.3, all state belonged to the "root"
   401  // module.
   402  type ModuleState struct {
   403  	// Path is the import path from the root module. Modules imports are
   404  	// always disjoint, so the path represents amodule tree
   405  	Path []string `json:"path"`
   406  
   407  	// Outputs declared by the module and maintained for each module
   408  	// even though only the root module technically needs to be kept.
   409  	// This allows operators to inspect values at the boundaries.
   410  	Outputs map[string]string `json:"outputs"`
   411  
   412  	// Resources is a mapping of the logically named resource to
   413  	// the state of the resource. Each resource may actually have
   414  	// N instances underneath, although a user only needs to think
   415  	// about the 1:1 case.
   416  	Resources map[string]*ResourceState `json:"resources"`
   417  
   418  	// Dependencies are a list of things that this module relies on
   419  	// existing to remain intact. For example: an module may depend
   420  	// on a VPC ID given by an aws_vpc resource.
   421  	//
   422  	// Terraform uses this information to build valid destruction
   423  	// orders and to warn the user if they're destroying a module that
   424  	// another resource depends on.
   425  	//
   426  	// Things can be put into this list that may not be managed by
   427  	// Terraform. If Terraform doesn't find a matching ID in the
   428  	// overall state, then it assumes it isn't managed and doesn't
   429  	// worry about it.
   430  	Dependencies []string `json:"depends_on,omitempty"`
   431  }
   432  
   433  // Equal tests whether one module state is equal to another.
   434  func (m *ModuleState) Equal(other *ModuleState) bool {
   435  	// Paths must be equal
   436  	if !reflect.DeepEqual(m.Path, other.Path) {
   437  		return false
   438  	}
   439  
   440  	// Outputs must be equal
   441  	if len(m.Outputs) != len(other.Outputs) {
   442  		return false
   443  	}
   444  	for k, v := range m.Outputs {
   445  		if other.Outputs[k] != v {
   446  			return false
   447  		}
   448  	}
   449  
   450  	// Dependencies must be equal. This sorts these in place but
   451  	// this shouldn't cause any problems.
   452  	sort.Strings(m.Dependencies)
   453  	sort.Strings(other.Dependencies)
   454  	if len(m.Dependencies) != len(other.Dependencies) {
   455  		return false
   456  	}
   457  	for i, d := range m.Dependencies {
   458  		if other.Dependencies[i] != d {
   459  			return false
   460  		}
   461  	}
   462  
   463  	// Resources must be equal
   464  	if len(m.Resources) != len(other.Resources) {
   465  		return false
   466  	}
   467  	for k, r := range m.Resources {
   468  		otherR, ok := other.Resources[k]
   469  		if !ok {
   470  			return false
   471  		}
   472  
   473  		if !r.Equal(otherR) {
   474  			return false
   475  		}
   476  	}
   477  
   478  	return true
   479  }
   480  
   481  // IsRoot says whether or not this module diff is for the root module.
   482  func (m *ModuleState) IsRoot() bool {
   483  	return reflect.DeepEqual(m.Path, rootModulePath)
   484  }
   485  
   486  // Orphans returns a list of keys of resources that are in the State
   487  // but aren't present in the configuration itself. Hence, these keys
   488  // represent the state of resources that are orphans.
   489  func (m *ModuleState) Orphans(c *config.Config) []string {
   490  	keys := make(map[string]struct{})
   491  	for k, _ := range m.Resources {
   492  		keys[k] = struct{}{}
   493  	}
   494  
   495  	if c != nil {
   496  		for _, r := range c.Resources {
   497  			delete(keys, r.Id())
   498  
   499  			for k, _ := range keys {
   500  				if strings.HasPrefix(k, r.Id()+".") {
   501  					delete(keys, k)
   502  				}
   503  			}
   504  		}
   505  	}
   506  
   507  	result := make([]string, 0, len(keys))
   508  	for k, _ := range keys {
   509  		result = append(result, k)
   510  	}
   511  
   512  	return result
   513  }
   514  
   515  // View returns a view with the given resource prefix.
   516  func (m *ModuleState) View(id string) *ModuleState {
   517  	if m == nil {
   518  		return m
   519  	}
   520  
   521  	r := m.deepcopy()
   522  	for k, _ := range r.Resources {
   523  		if id == k || strings.HasPrefix(k, id+".") {
   524  			continue
   525  		}
   526  
   527  		delete(r.Resources, k)
   528  	}
   529  
   530  	return r
   531  }
   532  
   533  func (m *ModuleState) init() {
   534  	if m.Outputs == nil {
   535  		m.Outputs = make(map[string]string)
   536  	}
   537  	if m.Resources == nil {
   538  		m.Resources = make(map[string]*ResourceState)
   539  	}
   540  }
   541  
   542  func (m *ModuleState) deepcopy() *ModuleState {
   543  	if m == nil {
   544  		return nil
   545  	}
   546  	n := &ModuleState{
   547  		Path:      make([]string, len(m.Path)),
   548  		Outputs:   make(map[string]string, len(m.Outputs)),
   549  		Resources: make(map[string]*ResourceState, len(m.Resources)),
   550  	}
   551  	copy(n.Path, m.Path)
   552  	for k, v := range m.Outputs {
   553  		n.Outputs[k] = v
   554  	}
   555  	for k, v := range m.Resources {
   556  		n.Resources[k] = v.deepcopy()
   557  	}
   558  	return n
   559  }
   560  
   561  // prune is used to remove any resources that are no longer required
   562  func (m *ModuleState) prune() {
   563  	for k, v := range m.Resources {
   564  		v.prune()
   565  
   566  		if (v.Primary == nil || v.Primary.ID == "") && len(v.Tainted) == 0 && len(v.Deposed) == 0 {
   567  			delete(m.Resources, k)
   568  		}
   569  	}
   570  
   571  	for k, v := range m.Outputs {
   572  		if v == config.UnknownVariableValue {
   573  			delete(m.Outputs, k)
   574  		}
   575  	}
   576  }
   577  
   578  func (m *ModuleState) sort() {
   579  	for _, v := range m.Resources {
   580  		v.sort()
   581  	}
   582  }
   583  
   584  func (m *ModuleState) GoString() string {
   585  	return fmt.Sprintf("*%#v", *m)
   586  }
   587  
   588  func (m *ModuleState) String() string {
   589  	var buf bytes.Buffer
   590  
   591  	if len(m.Resources) == 0 {
   592  		buf.WriteString("<no state>")
   593  	}
   594  
   595  	names := make([]string, 0, len(m.Resources))
   596  	for name, _ := range m.Resources {
   597  		names = append(names, name)
   598  	}
   599  	sort.Strings(names)
   600  
   601  	for _, k := range names {
   602  		rs := m.Resources[k]
   603  		var id string
   604  		if rs.Primary != nil {
   605  			id = rs.Primary.ID
   606  		}
   607  		if id == "" {
   608  			id = "<not created>"
   609  		}
   610  
   611  		taintStr := ""
   612  		if len(rs.Tainted) > 0 {
   613  			taintStr = fmt.Sprintf(" (%d tainted)", len(rs.Tainted))
   614  		}
   615  
   616  		deposedStr := ""
   617  		if len(rs.Deposed) > 0 {
   618  			deposedStr = fmt.Sprintf(" (%d deposed)", len(rs.Deposed))
   619  		}
   620  
   621  		buf.WriteString(fmt.Sprintf("%s:%s%s\n", k, taintStr, deposedStr))
   622  		buf.WriteString(fmt.Sprintf("  ID = %s\n", id))
   623  		if rs.Provider != "" {
   624  			buf.WriteString(fmt.Sprintf("  provider = %s\n", rs.Provider))
   625  		}
   626  
   627  		var attributes map[string]string
   628  		if rs.Primary != nil {
   629  			attributes = rs.Primary.Attributes
   630  		}
   631  		attrKeys := make([]string, 0, len(attributes))
   632  		for ak, _ := range attributes {
   633  			if ak == "id" {
   634  				continue
   635  			}
   636  
   637  			attrKeys = append(attrKeys, ak)
   638  		}
   639  		sort.Strings(attrKeys)
   640  
   641  		for _, ak := range attrKeys {
   642  			av := attributes[ak]
   643  			buf.WriteString(fmt.Sprintf("  %s = %s\n", ak, av))
   644  		}
   645  
   646  		for idx, t := range rs.Tainted {
   647  			buf.WriteString(fmt.Sprintf("  Tainted ID %d = %s\n", idx+1, t.ID))
   648  		}
   649  
   650  		for idx, t := range rs.Deposed {
   651  			buf.WriteString(fmt.Sprintf("  Deposed ID %d = %s\n", idx+1, t.ID))
   652  		}
   653  
   654  		if len(rs.Dependencies) > 0 {
   655  			buf.WriteString(fmt.Sprintf("\n  Dependencies:\n"))
   656  			for _, dep := range rs.Dependencies {
   657  				buf.WriteString(fmt.Sprintf("    %s\n", dep))
   658  			}
   659  		}
   660  	}
   661  
   662  	if len(m.Outputs) > 0 {
   663  		buf.WriteString("\nOutputs:\n\n")
   664  
   665  		ks := make([]string, 0, len(m.Outputs))
   666  		for k, _ := range m.Outputs {
   667  			ks = append(ks, k)
   668  		}
   669  		sort.Strings(ks)
   670  
   671  		for _, k := range ks {
   672  			v := m.Outputs[k]
   673  			buf.WriteString(fmt.Sprintf("%s = %s\n", k, v))
   674  		}
   675  	}
   676  
   677  	return buf.String()
   678  }
   679  
   680  // ResourceStateKey is a structured representation of the key used for the
   681  // ModuleState.Resources mapping
   682  type ResourceStateKey struct {
   683  	Name  string
   684  	Type  string
   685  	Index int
   686  }
   687  
   688  // Equal determines whether two ResourceStateKeys are the same
   689  func (rsk *ResourceStateKey) Equal(other *ResourceStateKey) bool {
   690  	if rsk == nil || other == nil {
   691  		return false
   692  	}
   693  	if rsk.Type != other.Type {
   694  		return false
   695  	}
   696  	if rsk.Name != other.Name {
   697  		return false
   698  	}
   699  	if rsk.Index != other.Index {
   700  		return false
   701  	}
   702  	return true
   703  }
   704  
   705  func (rsk *ResourceStateKey) String() string {
   706  	if rsk == nil {
   707  		return ""
   708  	}
   709  	if rsk.Index == -1 {
   710  		return fmt.Sprintf("%s.%s", rsk.Type, rsk.Name)
   711  	}
   712  	return fmt.Sprintf("%s.%s.%d", rsk.Type, rsk.Name, rsk.Index)
   713  }
   714  
   715  // ParseResourceStateKey accepts a key in the format used by
   716  // ModuleState.Resources and returns a resource name and resource index. In the
   717  // state, a resource has the format "type.name.index" or "type.name". In the
   718  // latter case, the index is returned as -1.
   719  func ParseResourceStateKey(k string) (*ResourceStateKey, error) {
   720  	parts := strings.Split(k, ".")
   721  	if len(parts) < 2 || len(parts) > 3 {
   722  		return nil, fmt.Errorf("Malformed resource state key: %s", k)
   723  	}
   724  	rsk := &ResourceStateKey{
   725  		Type:  parts[0],
   726  		Name:  parts[1],
   727  		Index: -1,
   728  	}
   729  	if len(parts) == 3 {
   730  		index, err := strconv.Atoi(parts[2])
   731  		if err != nil {
   732  			return nil, fmt.Errorf("Malformed resource state key index: %s", k)
   733  		}
   734  		rsk.Index = index
   735  	}
   736  	return rsk, nil
   737  }
   738  
   739  // ResourceState holds the state of a resource that is used so that
   740  // a provider can find and manage an existing resource as well as for
   741  // storing attributes that are used to populate variables of child
   742  // resources.
   743  //
   744  // Attributes has attributes about the created resource that are
   745  // queryable in interpolation: "${type.id.attr}"
   746  //
   747  // Extra is just extra data that a provider can return that we store
   748  // for later, but is not exposed in any way to the user.
   749  //
   750  type ResourceState struct {
   751  	// This is filled in and managed by Terraform, and is the resource
   752  	// type itself such as "mycloud_instance". If a resource provider sets
   753  	// this value, it won't be persisted.
   754  	Type string `json:"type"`
   755  
   756  	// Dependencies are a list of things that this resource relies on
   757  	// existing to remain intact. For example: an AWS instance might
   758  	// depend on a subnet (which itself might depend on a VPC, and so
   759  	// on).
   760  	//
   761  	// Terraform uses this information to build valid destruction
   762  	// orders and to warn the user if they're destroying a resource that
   763  	// another resource depends on.
   764  	//
   765  	// Things can be put into this list that may not be managed by
   766  	// Terraform. If Terraform doesn't find a matching ID in the
   767  	// overall state, then it assumes it isn't managed and doesn't
   768  	// worry about it.
   769  	Dependencies []string `json:"depends_on,omitempty"`
   770  
   771  	// Primary is the current active instance for this resource.
   772  	// It can be replaced but only after a successful creation.
   773  	// This is the instances on which providers will act.
   774  	Primary *InstanceState `json:"primary"`
   775  
   776  	// Tainted is used to track any underlying instances that
   777  	// have been created but are in a bad or unknown state and
   778  	// need to be cleaned up subsequently.  In the
   779  	// standard case, there is only at most a single instance.
   780  	// However, in pathological cases, it is possible for the number
   781  	// of instances to accumulate.
   782  	Tainted []*InstanceState `json:"tainted,omitempty"`
   783  
   784  	// Deposed is used in the mechanics of CreateBeforeDestroy: the existing
   785  	// Primary is Deposed to get it out of the way for the replacement Primary to
   786  	// be created by Apply. If the replacement Primary creates successfully, the
   787  	// Deposed instance is cleaned up. If there were problems creating the
   788  	// replacement, the instance remains in the Deposed list so it can be
   789  	// destroyed in a future run. Functionally, Deposed instances are very
   790  	// similar to Tainted instances in that Terraform is only tracking them in
   791  	// order to remember to destroy them.
   792  	Deposed []*InstanceState `json:"deposed,omitempty"`
   793  
   794  	// Provider is used when a resource is connected to a provider with an alias.
   795  	// If this string is empty, the resource is connected to the default provider,
   796  	// e.g. "aws_instance" goes with the "aws" provider.
   797  	// If the resource block contained a "provider" key, that value will be set here.
   798  	Provider string `json:"provider,omitempty"`
   799  }
   800  
   801  // Equal tests whether two ResourceStates are equal.
   802  func (s *ResourceState) Equal(other *ResourceState) bool {
   803  	if s.Type != other.Type {
   804  		return false
   805  	}
   806  
   807  	if s.Provider != other.Provider {
   808  		return false
   809  	}
   810  
   811  	// Dependencies must be equal
   812  	sort.Strings(s.Dependencies)
   813  	sort.Strings(other.Dependencies)
   814  	if len(s.Dependencies) != len(other.Dependencies) {
   815  		return false
   816  	}
   817  	for i, d := range s.Dependencies {
   818  		if other.Dependencies[i] != d {
   819  			return false
   820  		}
   821  	}
   822  
   823  	// States must be equal
   824  	if !s.Primary.Equal(other.Primary) {
   825  		return false
   826  	}
   827  
   828  	// Tainted
   829  	taints := make(map[string]*InstanceState)
   830  	for _, t := range other.Tainted {
   831  		if t == nil {
   832  			continue
   833  		}
   834  
   835  		taints[t.ID] = t
   836  	}
   837  	for _, t := range s.Tainted {
   838  		if t == nil {
   839  			continue
   840  		}
   841  
   842  		otherT, ok := taints[t.ID]
   843  		if !ok {
   844  			return false
   845  		}
   846  		delete(taints, t.ID)
   847  
   848  		if !t.Equal(otherT) {
   849  			return false
   850  		}
   851  	}
   852  
   853  	// This means that we have stuff in other tainted that we don't
   854  	// have, so it is not equal.
   855  	if len(taints) > 0 {
   856  		return false
   857  	}
   858  
   859  	return true
   860  }
   861  
   862  // Taint takes the primary state and marks it as tainted. If there is no
   863  // primary state, this does nothing.
   864  func (r *ResourceState) Taint() {
   865  	// If there is no primary, nothing to do
   866  	if r.Primary == nil {
   867  		return
   868  	}
   869  
   870  	// Shuffle to the end of the taint list and set primary to nil
   871  	r.Tainted = append(r.Tainted, r.Primary)
   872  	r.Primary = nil
   873  }
   874  
   875  // Untaint takes a tainted InstanceState and marks it as primary.
   876  // The index argument is used to select a single InstanceState from the
   877  // array of Tainted when there are more than one. If index is -1, the
   878  // first Tainted InstanceState will be untainted iff there is only one
   879  // Tainted InstanceState. Index must be >= 0 to specify an InstanceState
   880  // when Tainted has more than one member.
   881  func (r *ResourceState) Untaint(index int) error {
   882  	if len(r.Tainted) == 0 {
   883  		return fmt.Errorf("Nothing to untaint.")
   884  	}
   885  	if r.Primary != nil {
   886  		return fmt.Errorf("Resource has a primary instance in the state that would be overwritten by untainting. If you want to restore a tainted resource to primary, taint the existing primary instance first.")
   887  	}
   888  	if index == -1 && len(r.Tainted) > 1 {
   889  		return fmt.Errorf("There are %d tainted instances for this resource, please specify an index to select which one to untaint.", len(r.Tainted))
   890  	}
   891  	if index == -1 {
   892  		index = 0
   893  	}
   894  	if index >= len(r.Tainted) {
   895  		return fmt.Errorf("There are %d tainted instances for this resource, the index specified (%d) is out of range.", len(r.Tainted), index)
   896  	}
   897  
   898  	// Perform the untaint
   899  	r.Primary = r.Tainted[index]
   900  	r.Tainted = append(r.Tainted[:index], r.Tainted[index+1:]...)
   901  
   902  	return nil
   903  }
   904  
   905  func (r *ResourceState) init() {
   906  	if r.Primary == nil {
   907  		r.Primary = &InstanceState{}
   908  	}
   909  	r.Primary.init()
   910  }
   911  
   912  func (r *ResourceState) deepcopy() *ResourceState {
   913  	if r == nil {
   914  		return nil
   915  	}
   916  
   917  	n := &ResourceState{
   918  		Type:         r.Type,
   919  		Dependencies: nil,
   920  		Primary:      r.Primary.deepcopy(),
   921  		Tainted:      nil,
   922  		Provider:     r.Provider,
   923  	}
   924  	if r.Dependencies != nil {
   925  		n.Dependencies = make([]string, len(r.Dependencies))
   926  		copy(n.Dependencies, r.Dependencies)
   927  	}
   928  	if r.Tainted != nil {
   929  		n.Tainted = make([]*InstanceState, 0, len(r.Tainted))
   930  		for _, inst := range r.Tainted {
   931  			n.Tainted = append(n.Tainted, inst.deepcopy())
   932  		}
   933  	}
   934  	if r.Deposed != nil {
   935  		n.Deposed = make([]*InstanceState, 0, len(r.Deposed))
   936  		for _, inst := range r.Deposed {
   937  			n.Deposed = append(n.Deposed, inst.deepcopy())
   938  		}
   939  	}
   940  
   941  	return n
   942  }
   943  
   944  // prune is used to remove any instances that are no longer required
   945  func (r *ResourceState) prune() {
   946  	n := len(r.Tainted)
   947  	for i := 0; i < n; i++ {
   948  		inst := r.Tainted[i]
   949  		if inst == nil || inst.ID == "" {
   950  			copy(r.Tainted[i:], r.Tainted[i+1:])
   951  			r.Tainted[n-1] = nil
   952  			n--
   953  			i--
   954  		}
   955  	}
   956  
   957  	r.Tainted = r.Tainted[:n]
   958  
   959  	n = len(r.Deposed)
   960  	for i := 0; i < n; i++ {
   961  		inst := r.Deposed[i]
   962  		if inst == nil || inst.ID == "" {
   963  			copy(r.Deposed[i:], r.Deposed[i+1:])
   964  			r.Deposed[n-1] = nil
   965  			n--
   966  			i--
   967  		}
   968  	}
   969  
   970  	r.Deposed = r.Deposed[:n]
   971  }
   972  
   973  func (r *ResourceState) sort() {
   974  	sort.Strings(r.Dependencies)
   975  }
   976  
   977  func (s *ResourceState) GoString() string {
   978  	return fmt.Sprintf("*%#v", *s)
   979  }
   980  
   981  func (s *ResourceState) String() string {
   982  	var buf bytes.Buffer
   983  	buf.WriteString(fmt.Sprintf("Type = %s", s.Type))
   984  	return buf.String()
   985  }
   986  
   987  // InstanceState is used to track the unique state information belonging
   988  // to a given instance.
   989  type InstanceState struct {
   990  	// A unique ID for this resource. This is opaque to Terraform
   991  	// and is only meant as a lookup mechanism for the providers.
   992  	ID string `json:"id"`
   993  
   994  	// Attributes are basic information about the resource. Any keys here
   995  	// are accessible in variable format within Terraform configurations:
   996  	// ${resourcetype.name.attribute}.
   997  	Attributes map[string]string `json:"attributes,omitempty"`
   998  
   999  	// Ephemeral is used to store any state associated with this instance
  1000  	// that is necessary for the Terraform run to complete, but is not
  1001  	// persisted to a state file.
  1002  	Ephemeral EphemeralState `json:"-"`
  1003  
  1004  	// Meta is a simple K/V map that is persisted to the State but otherwise
  1005  	// ignored by Terraform core. It's meant to be used for accounting by
  1006  	// external client code.
  1007  	Meta map[string]string `json:"meta,omitempty"`
  1008  }
  1009  
  1010  func (i *InstanceState) init() {
  1011  	if i.Attributes == nil {
  1012  		i.Attributes = make(map[string]string)
  1013  	}
  1014  	if i.Meta == nil {
  1015  		i.Meta = make(map[string]string)
  1016  	}
  1017  	i.Ephemeral.init()
  1018  }
  1019  
  1020  func (i *InstanceState) deepcopy() *InstanceState {
  1021  	if i == nil {
  1022  		return nil
  1023  	}
  1024  	n := &InstanceState{
  1025  		ID:        i.ID,
  1026  		Ephemeral: *i.Ephemeral.deepcopy(),
  1027  	}
  1028  	if i.Attributes != nil {
  1029  		n.Attributes = make(map[string]string, len(i.Attributes))
  1030  		for k, v := range i.Attributes {
  1031  			n.Attributes[k] = v
  1032  		}
  1033  	}
  1034  	if i.Meta != nil {
  1035  		n.Meta = make(map[string]string, len(i.Meta))
  1036  		for k, v := range i.Meta {
  1037  			n.Meta[k] = v
  1038  		}
  1039  	}
  1040  	return n
  1041  }
  1042  
  1043  func (s *InstanceState) Empty() bool {
  1044  	return s == nil || s.ID == ""
  1045  }
  1046  
  1047  func (s *InstanceState) Equal(other *InstanceState) bool {
  1048  	// Short circuit some nil checks
  1049  	if s == nil || other == nil {
  1050  		return s == other
  1051  	}
  1052  
  1053  	// IDs must be equal
  1054  	if s.ID != other.ID {
  1055  		return false
  1056  	}
  1057  
  1058  	// Attributes must be equal
  1059  	if len(s.Attributes) != len(other.Attributes) {
  1060  		return false
  1061  	}
  1062  	for k, v := range s.Attributes {
  1063  		otherV, ok := other.Attributes[k]
  1064  		if !ok {
  1065  			return false
  1066  		}
  1067  
  1068  		if v != otherV {
  1069  			return false
  1070  		}
  1071  	}
  1072  
  1073  	// Meta must be equal
  1074  	if len(s.Meta) != len(other.Meta) {
  1075  		return false
  1076  	}
  1077  	for k, v := range s.Meta {
  1078  		otherV, ok := other.Meta[k]
  1079  		if !ok {
  1080  			return false
  1081  		}
  1082  
  1083  		if v != otherV {
  1084  			return false
  1085  		}
  1086  	}
  1087  
  1088  	return true
  1089  }
  1090  
  1091  // MergeDiff takes a ResourceDiff and merges the attributes into
  1092  // this resource state in order to generate a new state. This new
  1093  // state can be used to provide updated attribute lookups for
  1094  // variable interpolation.
  1095  //
  1096  // If the diff attribute requires computing the value, and hence
  1097  // won't be available until apply, the value is replaced with the
  1098  // computeID.
  1099  func (s *InstanceState) MergeDiff(d *InstanceDiff) *InstanceState {
  1100  	result := s.deepcopy()
  1101  	if result == nil {
  1102  		result = new(InstanceState)
  1103  	}
  1104  	result.init()
  1105  
  1106  	if s != nil {
  1107  		for k, v := range s.Attributes {
  1108  			result.Attributes[k] = v
  1109  		}
  1110  	}
  1111  	if d != nil {
  1112  		for k, diff := range d.Attributes {
  1113  			if diff.NewRemoved {
  1114  				delete(result.Attributes, k)
  1115  				continue
  1116  			}
  1117  			if diff.NewComputed {
  1118  				result.Attributes[k] = config.UnknownVariableValue
  1119  				continue
  1120  			}
  1121  
  1122  			result.Attributes[k] = diff.New
  1123  		}
  1124  	}
  1125  
  1126  	return result
  1127  }
  1128  
  1129  func (i *InstanceState) GoString() string {
  1130  	return fmt.Sprintf("*%#v", *i)
  1131  }
  1132  
  1133  func (i *InstanceState) String() string {
  1134  	var buf bytes.Buffer
  1135  
  1136  	if i == nil || i.ID == "" {
  1137  		return "<not created>"
  1138  	}
  1139  
  1140  	buf.WriteString(fmt.Sprintf("ID = %s\n", i.ID))
  1141  
  1142  	attributes := i.Attributes
  1143  	attrKeys := make([]string, 0, len(attributes))
  1144  	for ak, _ := range attributes {
  1145  		if ak == "id" {
  1146  			continue
  1147  		}
  1148  
  1149  		attrKeys = append(attrKeys, ak)
  1150  	}
  1151  	sort.Strings(attrKeys)
  1152  
  1153  	for _, ak := range attrKeys {
  1154  		av := attributes[ak]
  1155  		buf.WriteString(fmt.Sprintf("%s = %s\n", ak, av))
  1156  	}
  1157  
  1158  	return buf.String()
  1159  }
  1160  
  1161  // EphemeralState is used for transient state that is only kept in-memory
  1162  type EphemeralState struct {
  1163  	// ConnInfo is used for the providers to export information which is
  1164  	// used to connect to the resource for provisioning. For example,
  1165  	// this could contain SSH or WinRM credentials.
  1166  	ConnInfo map[string]string `json:"-"`
  1167  }
  1168  
  1169  func (e *EphemeralState) init() {
  1170  	if e.ConnInfo == nil {
  1171  		e.ConnInfo = make(map[string]string)
  1172  	}
  1173  }
  1174  
  1175  func (e *EphemeralState) deepcopy() *EphemeralState {
  1176  	if e == nil {
  1177  		return nil
  1178  	}
  1179  	n := &EphemeralState{}
  1180  	if e.ConnInfo != nil {
  1181  		n.ConnInfo = make(map[string]string, len(e.ConnInfo))
  1182  		for k, v := range e.ConnInfo {
  1183  			n.ConnInfo[k] = v
  1184  		}
  1185  	}
  1186  	return n
  1187  }
  1188  
  1189  // ReadState reads a state structure out of a reader in the format that
  1190  // was written by WriteState.
  1191  func ReadState(src io.Reader) (*State, error) {
  1192  	buf := bufio.NewReader(src)
  1193  
  1194  	// Check if this is a V1 format
  1195  	start, err := buf.Peek(len(stateFormatMagic))
  1196  	if err != nil {
  1197  		return nil, fmt.Errorf("Failed to check for magic bytes: %v", err)
  1198  	}
  1199  	if string(start) == stateFormatMagic {
  1200  		// Read the old state
  1201  		old, err := ReadStateV1(buf)
  1202  		if err != nil {
  1203  			return nil, err
  1204  		}
  1205  		return upgradeV1State(old)
  1206  	}
  1207  
  1208  	// Otherwise, must be V2
  1209  	dec := json.NewDecoder(buf)
  1210  	state := &State{}
  1211  	if err := dec.Decode(state); err != nil {
  1212  		return nil, fmt.Errorf("Decoding state file failed: %v", err)
  1213  	}
  1214  
  1215  	// Check the version, this to ensure we don't read a future
  1216  	// version that we don't understand
  1217  	if state.Version > StateVersion {
  1218  		return nil, fmt.Errorf("State version %d not supported, please update.",
  1219  			state.Version)
  1220  	}
  1221  
  1222  	// Sort it
  1223  	state.sort()
  1224  
  1225  	return state, nil
  1226  }
  1227  
  1228  // WriteState writes a state somewhere in a binary format.
  1229  func WriteState(d *State, dst io.Writer) error {
  1230  	// Make sure it is sorted
  1231  	d.sort()
  1232  
  1233  	// Ensure the version is set
  1234  	d.Version = StateVersion
  1235  
  1236  	// Encode the data in a human-friendly way
  1237  	data, err := json.MarshalIndent(d, "", "    ")
  1238  	if err != nil {
  1239  		return fmt.Errorf("Failed to encode state: %s", err)
  1240  	}
  1241  
  1242  	// We append a newline to the data because MarshalIndent doesn't
  1243  	data = append(data, '\n')
  1244  
  1245  	// Write the data out to the dst
  1246  	if _, err := io.Copy(dst, bytes.NewReader(data)); err != nil {
  1247  		return fmt.Errorf("Failed to write state: %v", err)
  1248  	}
  1249  
  1250  	return nil
  1251  }
  1252  
  1253  // upgradeV1State is used to upgrade a V1 state representation
  1254  // into a proper State representation.
  1255  func upgradeV1State(old *StateV1) (*State, error) {
  1256  	s := &State{}
  1257  	s.init()
  1258  
  1259  	// Old format had no modules, so we migrate everything
  1260  	// directly into the root module.
  1261  	root := s.RootModule()
  1262  
  1263  	// Copy the outputs
  1264  	root.Outputs = old.Outputs
  1265  
  1266  	// Upgrade the resources
  1267  	for id, rs := range old.Resources {
  1268  		newRs := &ResourceState{
  1269  			Type: rs.Type,
  1270  		}
  1271  		root.Resources[id] = newRs
  1272  
  1273  		// Migrate to an instance state
  1274  		instance := &InstanceState{
  1275  			ID:         rs.ID,
  1276  			Attributes: rs.Attributes,
  1277  		}
  1278  
  1279  		// Check if this is the primary or tainted instance
  1280  		if _, ok := old.Tainted[id]; ok {
  1281  			newRs.Tainted = append(newRs.Tainted, instance)
  1282  		} else {
  1283  			newRs.Primary = instance
  1284  		}
  1285  
  1286  		// Warn if the resource uses Extra, as there is
  1287  		// no upgrade path for this! Now totally deprecated.
  1288  		if len(rs.Extra) > 0 {
  1289  			log.Printf(
  1290  				"[WARN] Resource %s uses deprecated attribute "+
  1291  					"storage, state file upgrade may be incomplete.",
  1292  				rs.ID,
  1293  			)
  1294  		}
  1295  	}
  1296  	return s, nil
  1297  }
  1298  
  1299  // moduleStateSort implements sort.Interface to sort module states
  1300  type moduleStateSort []*ModuleState
  1301  
  1302  func (s moduleStateSort) Len() int {
  1303  	return len(s)
  1304  }
  1305  
  1306  func (s moduleStateSort) Less(i, j int) bool {
  1307  	a := s[i]
  1308  	b := s[j]
  1309  
  1310  	// If the lengths are different, then the shorter one always wins
  1311  	if len(a.Path) != len(b.Path) {
  1312  		return len(a.Path) < len(b.Path)
  1313  	}
  1314  
  1315  	// Otherwise, compare lexically
  1316  	return strings.Join(a.Path, ".") < strings.Join(b.Path, ".")
  1317  }
  1318  
  1319  func (s moduleStateSort) Swap(i, j int) {
  1320  	s[i], s[j] = s[j], s[i]
  1321  }