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