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