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