github.com/gavinw2006/hashicorp-terraform@v0.11.12-beta1/terraform/state.go (about) 1 package terraform 2 3 import ( 4 "bufio" 5 "bytes" 6 "encoding/json" 7 "errors" 8 "fmt" 9 "io" 10 "io/ioutil" 11 "log" 12 "os" 13 "reflect" 14 "sort" 15 "strconv" 16 "strings" 17 "sync" 18 19 "github.com/hashicorp/go-multierror" 20 "github.com/hashicorp/go-uuid" 21 "github.com/hashicorp/go-version" 22 "github.com/hashicorp/terraform/config" 23 "github.com/mitchellh/copystructure" 24 25 tfversion "github.com/hashicorp/terraform/version" 26 ) 27 28 const ( 29 // StateVersion is the current version for our state file 30 StateVersion = 3 31 ) 32 33 // rootModulePath is the path of the root module 34 var rootModulePath = []string{"root"} 35 36 // normalizeModulePath takes a raw module path and returns a path that 37 // has the rootModulePath prepended to it. If I could go back in time I 38 // would've never had a rootModulePath (empty path would be root). We can 39 // still fix this but thats a big refactor that my branch doesn't make sense 40 // for. Instead, this function normalizes paths. 41 func normalizeModulePath(p []string) []string { 42 k := len(rootModulePath) 43 44 // If we already have a root module prefix, we're done 45 if len(p) >= len(rootModulePath) { 46 if reflect.DeepEqual(p[:k], rootModulePath) { 47 return p 48 } 49 } 50 51 // None? Prefix it 52 result := make([]string, len(rootModulePath)+len(p)) 53 copy(result, rootModulePath) 54 copy(result[k:], p) 55 return result 56 } 57 58 // State keeps track of a snapshot state-of-the-world that Terraform 59 // can use to keep track of what real world resources it is actually 60 // managing. 61 type State struct { 62 // Version is the state file protocol version. 63 Version int `json:"version"` 64 65 // TFVersion is the version of Terraform that wrote this state. 66 TFVersion string `json:"terraform_version,omitempty"` 67 68 // Serial is incremented on any operation that modifies 69 // the State file. It is used to detect potentially conflicting 70 // updates. 71 Serial int64 `json:"serial"` 72 73 // Lineage is set when a new, blank state is created and then 74 // never updated. This allows us to determine whether the serials 75 // of two states can be meaningfully compared. 76 // Apart from the guarantee that collisions between two lineages 77 // are very unlikely, this value is opaque and external callers 78 // should only compare lineage strings byte-for-byte for equality. 79 Lineage string `json:"lineage"` 80 81 // Remote is used to track the metadata required to 82 // pull and push state files from a remote storage endpoint. 83 Remote *RemoteState `json:"remote,omitempty"` 84 85 // Backend tracks the configuration for the backend in use with 86 // this state. This is used to track any changes in the backend 87 // configuration. 88 Backend *BackendState `json:"backend,omitempty"` 89 90 // Modules contains all the modules in a breadth-first order 91 Modules []*ModuleState `json:"modules"` 92 93 mu sync.Mutex 94 } 95 96 func (s *State) Lock() { s.mu.Lock() } 97 func (s *State) Unlock() { s.mu.Unlock() } 98 99 // NewState is used to initialize a blank state 100 func NewState() *State { 101 s := &State{} 102 s.init() 103 return s 104 } 105 106 // Children returns the ModuleStates that are direct children of 107 // the given path. If the path is "root", for example, then children 108 // returned might be "root.child", but not "root.child.grandchild". 109 func (s *State) Children(path []string) []*ModuleState { 110 s.Lock() 111 defer s.Unlock() 112 // TODO: test 113 114 return s.children(path) 115 } 116 117 func (s *State) children(path []string) []*ModuleState { 118 result := make([]*ModuleState, 0) 119 for _, m := range s.Modules { 120 if m == nil { 121 continue 122 } 123 124 if len(m.Path) != len(path)+1 { 125 continue 126 } 127 if !reflect.DeepEqual(path, m.Path[:len(path)]) { 128 continue 129 } 130 131 result = append(result, m) 132 } 133 134 return result 135 } 136 137 // AddModule adds the module with the given path to the state. 138 // 139 // This should be the preferred method to add module states since it 140 // allows us to optimize lookups later as well as control sorting. 141 func (s *State) AddModule(path []string) *ModuleState { 142 s.Lock() 143 defer s.Unlock() 144 145 return s.addModule(path) 146 } 147 148 func (s *State) addModule(path []string) *ModuleState { 149 // check if the module exists first 150 m := s.moduleByPath(path) 151 if m != nil { 152 return m 153 } 154 155 m = &ModuleState{Path: path} 156 m.init() 157 s.Modules = append(s.Modules, m) 158 s.sort() 159 return m 160 } 161 162 // ModuleByPath is used to lookup the module state for the given path. 163 // This should be the preferred lookup mechanism as it allows for future 164 // lookup optimizations. 165 func (s *State) ModuleByPath(path []string) *ModuleState { 166 if s == nil { 167 return nil 168 } 169 s.Lock() 170 defer s.Unlock() 171 172 return s.moduleByPath(path) 173 } 174 175 func (s *State) moduleByPath(path []string) *ModuleState { 176 for _, mod := range s.Modules { 177 if mod == nil { 178 continue 179 } 180 if mod.Path == nil { 181 panic("missing module path") 182 } 183 if reflect.DeepEqual(mod.Path, path) { 184 return mod 185 } 186 } 187 return nil 188 } 189 190 // ModuleOrphans returns all the module orphans in this state by 191 // returning their full paths. These paths can be used with ModuleByPath 192 // to return the actual state. 193 func (s *State) ModuleOrphans(path []string, c *config.Config) [][]string { 194 s.Lock() 195 defer s.Unlock() 196 197 return s.moduleOrphans(path, c) 198 199 } 200 201 func (s *State) moduleOrphans(path []string, c *config.Config) [][]string { 202 // direct keeps track of what direct children we have both in our config 203 // and in our state. childrenKeys keeps track of what isn't an orphan. 204 direct := make(map[string]struct{}) 205 childrenKeys := make(map[string]struct{}) 206 if c != nil { 207 for _, m := range c.Modules { 208 childrenKeys[m.Name] = struct{}{} 209 direct[m.Name] = struct{}{} 210 } 211 } 212 213 // Go over the direct children and find any that aren't in our keys. 214 var orphans [][]string 215 for _, m := range s.children(path) { 216 key := m.Path[len(m.Path)-1] 217 218 // Record that we found this key as a direct child. We use this 219 // later to find orphan nested modules. 220 direct[key] = struct{}{} 221 222 // If we have a direct child still in our config, it is not an orphan 223 if _, ok := childrenKeys[key]; ok { 224 continue 225 } 226 227 orphans = append(orphans, m.Path) 228 } 229 230 // Find the orphans that are nested... 231 for _, m := range s.Modules { 232 if m == nil { 233 continue 234 } 235 236 // We only want modules that are at least grandchildren 237 if len(m.Path) < len(path)+2 { 238 continue 239 } 240 241 // If it isn't part of our tree, continue 242 if !reflect.DeepEqual(path, m.Path[:len(path)]) { 243 continue 244 } 245 246 // If we have the direct child, then just skip it. 247 key := m.Path[len(path)] 248 if _, ok := direct[key]; ok { 249 continue 250 } 251 252 orphanPath := m.Path[:len(path)+1] 253 254 // Don't double-add if we've already added this orphan (which can happen if 255 // there are multiple nested sub-modules that get orphaned together). 256 alreadyAdded := false 257 for _, o := range orphans { 258 if reflect.DeepEqual(o, orphanPath) { 259 alreadyAdded = true 260 break 261 } 262 } 263 if alreadyAdded { 264 continue 265 } 266 267 // Add this orphan 268 orphans = append(orphans, orphanPath) 269 } 270 271 return orphans 272 } 273 274 // Empty returns true if the state is empty. 275 func (s *State) Empty() bool { 276 if s == nil { 277 return true 278 } 279 s.Lock() 280 defer s.Unlock() 281 282 return len(s.Modules) == 0 283 } 284 285 // HasResources returns true if the state contains any resources. 286 // 287 // This is similar to !s.Empty, but returns true also in the case where the 288 // state has modules but all of them are devoid of resources. 289 func (s *State) HasResources() bool { 290 if s.Empty() { 291 return false 292 } 293 294 for _, mod := range s.Modules { 295 if len(mod.Resources) > 0 { 296 return true 297 } 298 } 299 300 return false 301 } 302 303 // IsRemote returns true if State represents a state that exists and is 304 // remote. 305 func (s *State) IsRemote() bool { 306 if s == nil { 307 return false 308 } 309 s.Lock() 310 defer s.Unlock() 311 312 if s.Remote == nil { 313 return false 314 } 315 if s.Remote.Type == "" { 316 return false 317 } 318 319 return true 320 } 321 322 // Validate validates the integrity of this state file. 323 // 324 // Certain properties of the statefile are expected by Terraform in order 325 // to behave properly. The core of Terraform will assume that once it 326 // receives a State structure that it has been validated. This validation 327 // check should be called to ensure that. 328 // 329 // If this returns an error, then the user should be notified. The error 330 // response will include detailed information on the nature of the error. 331 func (s *State) Validate() error { 332 s.Lock() 333 defer s.Unlock() 334 335 var result error 336 337 // !!!! FOR DEVELOPERS !!!! 338 // 339 // Any errors returned from this Validate function will BLOCK TERRAFORM 340 // from loading a state file. Therefore, this should only contain checks 341 // that are only resolvable through manual intervention. 342 // 343 // !!!! FOR DEVELOPERS !!!! 344 345 // Make sure there are no duplicate module states. We open a new 346 // block here so we can use basic variable names and future validations 347 // can do the same. 348 { 349 found := make(map[string]struct{}) 350 for _, ms := range s.Modules { 351 if ms == nil { 352 continue 353 } 354 355 key := strings.Join(ms.Path, ".") 356 if _, ok := found[key]; ok { 357 result = multierror.Append(result, fmt.Errorf( 358 strings.TrimSpace(stateValidateErrMultiModule), key)) 359 continue 360 } 361 362 found[key] = struct{}{} 363 } 364 } 365 366 return result 367 } 368 369 // Remove removes the item in the state at the given address, returning 370 // any errors that may have occurred. 371 // 372 // If the address references a module state or resource, it will delete 373 // all children as well. To check what will be deleted, use a StateFilter 374 // first. 375 func (s *State) Remove(addr ...string) error { 376 s.Lock() 377 defer s.Unlock() 378 379 // Filter out what we need to delete 380 filter := &StateFilter{State: s} 381 results, err := filter.Filter(addr...) 382 if err != nil { 383 return err 384 } 385 386 // If we have no results, just exit early, we're not going to do anything. 387 // While what happens below is fairly fast, this is an important early 388 // exit since the prune below might modify the state more and we don't 389 // want to modify the state if we don't have to. 390 if len(results) == 0 { 391 return nil 392 } 393 394 // Go through each result and grab what we need 395 removed := make(map[interface{}]struct{}) 396 for _, r := range results { 397 // Convert the path to our own type 398 path := append([]string{"root"}, r.Path...) 399 400 // If we removed this already, then ignore 401 if _, ok := removed[r.Value]; ok { 402 continue 403 } 404 405 // If we removed the parent already, then ignore 406 if r.Parent != nil { 407 if _, ok := removed[r.Parent.Value]; ok { 408 continue 409 } 410 } 411 412 // Add this to the removed list 413 removed[r.Value] = struct{}{} 414 415 switch v := r.Value.(type) { 416 case *ModuleState: 417 s.removeModule(path, v) 418 case *ResourceState: 419 s.removeResource(path, v) 420 case *InstanceState: 421 s.removeInstance(path, r.Parent.Value.(*ResourceState), v) 422 default: 423 return fmt.Errorf("unknown type to delete: %T", r.Value) 424 } 425 } 426 427 // Prune since the removal functions often do the bare minimum to 428 // remove a thing and may leave around dangling empty modules, resources, 429 // etc. Prune will clean that all up. 430 s.prune() 431 432 return nil 433 } 434 435 func (s *State) removeModule(path []string, v *ModuleState) { 436 for i, m := range s.Modules { 437 if m == v { 438 s.Modules, s.Modules[len(s.Modules)-1] = append(s.Modules[:i], s.Modules[i+1:]...), nil 439 return 440 } 441 } 442 } 443 444 func (s *State) removeResource(path []string, v *ResourceState) { 445 // Get the module this resource lives in. If it doesn't exist, we're done. 446 mod := s.moduleByPath(path) 447 if mod == nil { 448 return 449 } 450 451 // Find this resource. This is a O(N) lookup when if we had the key 452 // it could be O(1) but even with thousands of resources this shouldn't 453 // matter right now. We can easily up performance here when the time comes. 454 for k, r := range mod.Resources { 455 if r == v { 456 // Found it 457 delete(mod.Resources, k) 458 return 459 } 460 } 461 } 462 463 func (s *State) removeInstance(path []string, r *ResourceState, v *InstanceState) { 464 // Go through the resource and find the instance that matches this 465 // (if any) and remove it. 466 467 // Check primary 468 if r.Primary == v { 469 r.Primary = nil 470 return 471 } 472 473 // Check lists 474 lists := [][]*InstanceState{r.Deposed} 475 for _, is := range lists { 476 for i, instance := range is { 477 if instance == v { 478 // Found it, remove it 479 is, is[len(is)-1] = append(is[:i], is[i+1:]...), nil 480 481 // Done 482 return 483 } 484 } 485 } 486 } 487 488 // RootModule returns the ModuleState for the root module 489 func (s *State) RootModule() *ModuleState { 490 root := s.ModuleByPath(rootModulePath) 491 if root == nil { 492 panic("missing root module") 493 } 494 return root 495 } 496 497 // Equal tests if one state is equal to another. 498 func (s *State) Equal(other *State) bool { 499 // If one is nil, we do a direct check 500 if s == nil || other == nil { 501 return s == other 502 } 503 504 s.Lock() 505 defer s.Unlock() 506 return s.equal(other) 507 } 508 509 func (s *State) equal(other *State) bool { 510 if s == nil || other == nil { 511 return s == other 512 } 513 514 // If the versions are different, they're certainly not equal 515 if s.Version != other.Version { 516 return false 517 } 518 519 // If any of the modules are not equal, then this state isn't equal 520 if len(s.Modules) != len(other.Modules) { 521 return false 522 } 523 for _, m := range s.Modules { 524 // This isn't very optimal currently but works. 525 otherM := other.moduleByPath(m.Path) 526 if otherM == nil { 527 return false 528 } 529 530 // If they're not equal, then we're not equal! 531 if !m.Equal(otherM) { 532 return false 533 } 534 } 535 536 return true 537 } 538 539 // MarshalEqual is similar to Equal but provides a stronger definition of 540 // "equal", where two states are equal if and only if their serialized form 541 // is byte-for-byte identical. 542 // 543 // This is primarily useful for callers that are trying to save snapshots 544 // of state to persistent storage, allowing them to detect when a new 545 // snapshot must be taken. 546 // 547 // Note that the serial number and lineage are included in the serialized form, 548 // so it's the caller's responsibility to properly manage these attributes 549 // so that this method is only called on two states that have the same 550 // serial and lineage, unless detecting such differences is desired. 551 func (s *State) MarshalEqual(other *State) bool { 552 if s == nil && other == nil { 553 return true 554 } else if s == nil || other == nil { 555 return false 556 } 557 558 recvBuf := &bytes.Buffer{} 559 otherBuf := &bytes.Buffer{} 560 561 err := WriteState(s, recvBuf) 562 if err != nil { 563 // should never happen, since we're writing to a buffer 564 panic(err) 565 } 566 567 err = WriteState(other, otherBuf) 568 if err != nil { 569 // should never happen, since we're writing to a buffer 570 panic(err) 571 } 572 573 return bytes.Equal(recvBuf.Bytes(), otherBuf.Bytes()) 574 } 575 576 type StateAgeComparison int 577 578 const ( 579 StateAgeEqual StateAgeComparison = 0 580 StateAgeReceiverNewer StateAgeComparison = 1 581 StateAgeReceiverOlder StateAgeComparison = -1 582 ) 583 584 // CompareAges compares one state with another for which is "older". 585 // 586 // This is a simple check using the state's serial, and is thus only as 587 // reliable as the serial itself. In the normal case, only one state 588 // exists for a given combination of lineage/serial, but Terraform 589 // does not guarantee this and so the result of this method should be 590 // used with care. 591 // 592 // Returns an integer that is negative if the receiver is older than 593 // the argument, positive if the converse, and zero if they are equal. 594 // An error is returned if the two states are not of the same lineage, 595 // in which case the integer returned has no meaning. 596 func (s *State) CompareAges(other *State) (StateAgeComparison, error) { 597 // nil states are "older" than actual states 598 switch { 599 case s != nil && other == nil: 600 return StateAgeReceiverNewer, nil 601 case s == nil && other != nil: 602 return StateAgeReceiverOlder, nil 603 case s == nil && other == nil: 604 return StateAgeEqual, nil 605 } 606 607 if !s.SameLineage(other) { 608 return StateAgeEqual, fmt.Errorf( 609 "can't compare two states of differing lineage", 610 ) 611 } 612 613 s.Lock() 614 defer s.Unlock() 615 616 switch { 617 case s.Serial < other.Serial: 618 return StateAgeReceiverOlder, nil 619 case s.Serial > other.Serial: 620 return StateAgeReceiverNewer, nil 621 default: 622 return StateAgeEqual, nil 623 } 624 } 625 626 // SameLineage returns true only if the state given in argument belongs 627 // to the same "lineage" of states as the receiver. 628 func (s *State) SameLineage(other *State) bool { 629 s.Lock() 630 defer s.Unlock() 631 632 // If one of the states has no lineage then it is assumed to predate 633 // this concept, and so we'll accept it as belonging to any lineage 634 // so that a lineage string can be assigned to newer versions 635 // without breaking compatibility with older versions. 636 if s.Lineage == "" || other.Lineage == "" { 637 return true 638 } 639 640 return s.Lineage == other.Lineage 641 } 642 643 // DeepCopy performs a deep copy of the state structure and returns 644 // a new structure. 645 func (s *State) DeepCopy() *State { 646 if s == nil { 647 return nil 648 } 649 650 copy, err := copystructure.Config{Lock: true}.Copy(s) 651 if err != nil { 652 panic(err) 653 } 654 655 return copy.(*State) 656 } 657 658 // FromFutureTerraform checks if this state was written by a Terraform 659 // version from the future. 660 func (s *State) FromFutureTerraform() bool { 661 s.Lock() 662 defer s.Unlock() 663 664 // No TF version means it is certainly from the past 665 if s.TFVersion == "" { 666 return false 667 } 668 669 v := version.Must(version.NewVersion(s.TFVersion)) 670 return tfversion.SemVer.LessThan(v) 671 } 672 673 func (s *State) Init() { 674 s.Lock() 675 defer s.Unlock() 676 s.init() 677 } 678 679 func (s *State) init() { 680 if s.Version == 0 { 681 s.Version = StateVersion 682 } 683 684 if s.moduleByPath(rootModulePath) == nil { 685 s.addModule(rootModulePath) 686 } 687 s.ensureHasLineage() 688 689 for _, mod := range s.Modules { 690 if mod != nil { 691 mod.init() 692 } 693 } 694 695 if s.Remote != nil { 696 s.Remote.init() 697 } 698 699 } 700 701 func (s *State) EnsureHasLineage() { 702 s.Lock() 703 defer s.Unlock() 704 705 s.ensureHasLineage() 706 } 707 708 func (s *State) ensureHasLineage() { 709 if s.Lineage == "" { 710 lineage, err := uuid.GenerateUUID() 711 if err != nil { 712 panic(fmt.Errorf("Failed to generate lineage: %v", err)) 713 } 714 s.Lineage = lineage 715 log.Printf("[DEBUG] New state was assigned lineage %q\n", s.Lineage) 716 } else { 717 log.Printf("[TRACE] Preserving existing state lineage %q\n", s.Lineage) 718 } 719 } 720 721 // AddModuleState insert this module state and override any existing ModuleState 722 func (s *State) AddModuleState(mod *ModuleState) { 723 mod.init() 724 s.Lock() 725 defer s.Unlock() 726 727 s.addModuleState(mod) 728 } 729 730 func (s *State) addModuleState(mod *ModuleState) { 731 for i, m := range s.Modules { 732 if reflect.DeepEqual(m.Path, mod.Path) { 733 s.Modules[i] = mod 734 return 735 } 736 } 737 738 s.Modules = append(s.Modules, mod) 739 s.sort() 740 } 741 742 // prune is used to remove any resources that are no longer required 743 func (s *State) prune() { 744 if s == nil { 745 return 746 } 747 748 // Filter out empty modules. 749 // A module is always assumed to have a path, and it's length isn't always 750 // bounds checked later on. Modules may be "emptied" during destroy, but we 751 // never want to store those in the state. 752 for i := 0; i < len(s.Modules); i++ { 753 if s.Modules[i] == nil || len(s.Modules[i].Path) == 0 { 754 s.Modules = append(s.Modules[:i], s.Modules[i+1:]...) 755 i-- 756 } 757 } 758 759 for _, mod := range s.Modules { 760 mod.prune() 761 } 762 if s.Remote != nil && s.Remote.Empty() { 763 s.Remote = nil 764 } 765 } 766 767 // sort sorts the modules 768 func (s *State) sort() { 769 sort.Sort(moduleStateSort(s.Modules)) 770 771 // Allow modules to be sorted 772 for _, m := range s.Modules { 773 if m != nil { 774 m.sort() 775 } 776 } 777 } 778 779 func (s *State) String() string { 780 if s == nil { 781 return "<nil>" 782 } 783 s.Lock() 784 defer s.Unlock() 785 786 var buf bytes.Buffer 787 for _, m := range s.Modules { 788 mStr := m.String() 789 790 // If we're the root module, we just write the output directly. 791 if reflect.DeepEqual(m.Path, rootModulePath) { 792 buf.WriteString(mStr + "\n") 793 continue 794 } 795 796 buf.WriteString(fmt.Sprintf("module.%s:\n", strings.Join(m.Path[1:], "."))) 797 798 s := bufio.NewScanner(strings.NewReader(mStr)) 799 for s.Scan() { 800 text := s.Text() 801 if text != "" { 802 text = " " + text 803 } 804 805 buf.WriteString(fmt.Sprintf("%s\n", text)) 806 } 807 } 808 809 return strings.TrimSpace(buf.String()) 810 } 811 812 // BackendState stores the configuration to connect to a remote backend. 813 type BackendState struct { 814 Type string `json:"type"` // Backend type 815 Config map[string]interface{} `json:"config"` // Backend raw config 816 817 // Hash is the hash code to uniquely identify the original source 818 // configuration. We use this to detect when there is a change in 819 // configuration even when "type" isn't changed. 820 Hash uint64 `json:"hash"` 821 } 822 823 // Empty returns true if BackendState has no state. 824 func (s *BackendState) Empty() bool { 825 return s == nil || s.Type == "" 826 } 827 828 // Rehash returns a unique content hash for this backend's configuration 829 // as a uint64 value. 830 // The Hash stored in the backend state needs to match the config itself, but 831 // we need to compare the backend config after it has been combined with all 832 // options. 833 // This function must match the implementation used by config.Backend. 834 func (s *BackendState) Rehash() uint64 { 835 if s == nil { 836 return 0 837 } 838 839 cfg := config.Backend{ 840 Type: s.Type, 841 RawConfig: &config.RawConfig{ 842 Raw: s.Config, 843 }, 844 } 845 846 return cfg.Rehash() 847 } 848 849 // RemoteState is used to track the information about a remote 850 // state store that we push/pull state to. 851 type RemoteState struct { 852 // Type controls the client we use for the remote state 853 Type string `json:"type"` 854 855 // Config is used to store arbitrary configuration that 856 // is type specific 857 Config map[string]string `json:"config"` 858 859 mu sync.Mutex 860 } 861 862 func (s *RemoteState) Lock() { s.mu.Lock() } 863 func (s *RemoteState) Unlock() { s.mu.Unlock() } 864 865 func (r *RemoteState) init() { 866 r.Lock() 867 defer r.Unlock() 868 869 if r.Config == nil { 870 r.Config = make(map[string]string) 871 } 872 } 873 874 func (r *RemoteState) deepcopy() *RemoteState { 875 r.Lock() 876 defer r.Unlock() 877 878 confCopy := make(map[string]string, len(r.Config)) 879 for k, v := range r.Config { 880 confCopy[k] = v 881 } 882 return &RemoteState{ 883 Type: r.Type, 884 Config: confCopy, 885 } 886 } 887 888 func (r *RemoteState) Empty() bool { 889 if r == nil { 890 return true 891 } 892 r.Lock() 893 defer r.Unlock() 894 895 return r.Type == "" 896 } 897 898 func (r *RemoteState) Equals(other *RemoteState) bool { 899 r.Lock() 900 defer r.Unlock() 901 902 if r.Type != other.Type { 903 return false 904 } 905 if len(r.Config) != len(other.Config) { 906 return false 907 } 908 for k, v := range r.Config { 909 if other.Config[k] != v { 910 return false 911 } 912 } 913 return true 914 } 915 916 // OutputState is used to track the state relevant to a single output. 917 type OutputState struct { 918 // Sensitive describes whether the output is considered sensitive, 919 // which may lead to masking the value on screen in some cases. 920 Sensitive bool `json:"sensitive"` 921 // Type describes the structure of Value. Valid values are "string", 922 // "map" and "list" 923 Type string `json:"type"` 924 // Value contains the value of the output, in the structure described 925 // by the Type field. 926 Value interface{} `json:"value"` 927 928 mu sync.Mutex 929 } 930 931 func (s *OutputState) Lock() { s.mu.Lock() } 932 func (s *OutputState) Unlock() { s.mu.Unlock() } 933 934 func (s *OutputState) String() string { 935 return fmt.Sprintf("%#v", s.Value) 936 } 937 938 // Equal compares two OutputState structures for equality. nil values are 939 // considered equal. 940 func (s *OutputState) Equal(other *OutputState) bool { 941 if s == nil && other == nil { 942 return true 943 } 944 945 if s == nil || other == nil { 946 return false 947 } 948 s.Lock() 949 defer s.Unlock() 950 951 if s.Type != other.Type { 952 return false 953 } 954 955 if s.Sensitive != other.Sensitive { 956 return false 957 } 958 959 if !reflect.DeepEqual(s.Value, other.Value) { 960 return false 961 } 962 963 return true 964 } 965 966 func (s *OutputState) deepcopy() *OutputState { 967 if s == nil { 968 return nil 969 } 970 971 stateCopy, err := copystructure.Config{Lock: true}.Copy(s) 972 if err != nil { 973 panic(fmt.Errorf("Error copying output value: %s", err)) 974 } 975 976 return stateCopy.(*OutputState) 977 } 978 979 // ModuleState is used to track all the state relevant to a single 980 // module. Previous to Terraform 0.3, all state belonged to the "root" 981 // module. 982 type ModuleState struct { 983 // Path is the import path from the root module. Modules imports are 984 // always disjoint, so the path represents amodule tree 985 Path []string `json:"path"` 986 987 // Locals are kept only transiently in-memory, because we can always 988 // re-compute them. 989 Locals map[string]interface{} `json:"-"` 990 991 // Outputs declared by the module and maintained for each module 992 // even though only the root module technically needs to be kept. 993 // This allows operators to inspect values at the boundaries. 994 Outputs map[string]*OutputState `json:"outputs"` 995 996 // Resources is a mapping of the logically named resource to 997 // the state of the resource. Each resource may actually have 998 // N instances underneath, although a user only needs to think 999 // about the 1:1 case. 1000 Resources map[string]*ResourceState `json:"resources"` 1001 1002 // Dependencies are a list of things that this module relies on 1003 // existing to remain intact. For example: an module may depend 1004 // on a VPC ID given by an aws_vpc resource. 1005 // 1006 // Terraform uses this information to build valid destruction 1007 // orders and to warn the user if they're destroying a module that 1008 // another resource depends on. 1009 // 1010 // Things can be put into this list that may not be managed by 1011 // Terraform. If Terraform doesn't find a matching ID in the 1012 // overall state, then it assumes it isn't managed and doesn't 1013 // worry about it. 1014 Dependencies []string `json:"depends_on"` 1015 1016 mu sync.Mutex 1017 } 1018 1019 func (s *ModuleState) Lock() { s.mu.Lock() } 1020 func (s *ModuleState) Unlock() { s.mu.Unlock() } 1021 1022 // Equal tests whether one module state is equal to another. 1023 func (m *ModuleState) Equal(other *ModuleState) bool { 1024 m.Lock() 1025 defer m.Unlock() 1026 1027 // Paths must be equal 1028 if !reflect.DeepEqual(m.Path, other.Path) { 1029 return false 1030 } 1031 1032 // Outputs must be equal 1033 if len(m.Outputs) != len(other.Outputs) { 1034 return false 1035 } 1036 for k, v := range m.Outputs { 1037 if !other.Outputs[k].Equal(v) { 1038 return false 1039 } 1040 } 1041 1042 // Dependencies must be equal. This sorts these in place but 1043 // this shouldn't cause any problems. 1044 sort.Strings(m.Dependencies) 1045 sort.Strings(other.Dependencies) 1046 if len(m.Dependencies) != len(other.Dependencies) { 1047 return false 1048 } 1049 for i, d := range m.Dependencies { 1050 if other.Dependencies[i] != d { 1051 return false 1052 } 1053 } 1054 1055 // Resources must be equal 1056 if len(m.Resources) != len(other.Resources) { 1057 return false 1058 } 1059 for k, r := range m.Resources { 1060 otherR, ok := other.Resources[k] 1061 if !ok { 1062 return false 1063 } 1064 1065 if !r.Equal(otherR) { 1066 return false 1067 } 1068 } 1069 1070 return true 1071 } 1072 1073 // IsRoot says whether or not this module diff is for the root module. 1074 func (m *ModuleState) IsRoot() bool { 1075 m.Lock() 1076 defer m.Unlock() 1077 return reflect.DeepEqual(m.Path, rootModulePath) 1078 } 1079 1080 // IsDescendent returns true if other is a descendent of this module. 1081 func (m *ModuleState) IsDescendent(other *ModuleState) bool { 1082 m.Lock() 1083 defer m.Unlock() 1084 1085 i := len(m.Path) 1086 return len(other.Path) > i && reflect.DeepEqual(other.Path[:i], m.Path) 1087 } 1088 1089 // Orphans returns a list of keys of resources that are in the State 1090 // but aren't present in the configuration itself. Hence, these keys 1091 // represent the state of resources that are orphans. 1092 func (m *ModuleState) Orphans(c *config.Config) []string { 1093 m.Lock() 1094 defer m.Unlock() 1095 1096 keys := make(map[string]struct{}) 1097 for k := range m.Resources { 1098 keys[k] = struct{}{} 1099 } 1100 1101 if c != nil { 1102 for _, r := range c.Resources { 1103 delete(keys, r.Id()) 1104 1105 for k := range keys { 1106 if strings.HasPrefix(k, r.Id()+".") { 1107 delete(keys, k) 1108 } 1109 } 1110 } 1111 } 1112 1113 result := make([]string, 0, len(keys)) 1114 for k := range keys { 1115 result = append(result, k) 1116 } 1117 1118 return result 1119 } 1120 1121 // RemovedOutputs returns a list of outputs that are in the State but aren't 1122 // present in the configuration itself. 1123 func (m *ModuleState) RemovedOutputs(c *config.Config) []string { 1124 m.Lock() 1125 defer m.Unlock() 1126 1127 keys := make(map[string]struct{}) 1128 for k := range m.Outputs { 1129 keys[k] = struct{}{} 1130 } 1131 1132 if c != nil { 1133 for _, o := range c.Outputs { 1134 delete(keys, o.Name) 1135 } 1136 } 1137 1138 result := make([]string, 0, len(keys)) 1139 for k := range keys { 1140 result = append(result, k) 1141 } 1142 1143 return result 1144 } 1145 1146 // View returns a view with the given resource prefix. 1147 func (m *ModuleState) View(id string) *ModuleState { 1148 if m == nil { 1149 return m 1150 } 1151 1152 r := m.deepcopy() 1153 for k, _ := range r.Resources { 1154 if id == k || strings.HasPrefix(k, id+".") { 1155 continue 1156 } 1157 1158 delete(r.Resources, k) 1159 } 1160 1161 return r 1162 } 1163 1164 func (m *ModuleState) init() { 1165 m.Lock() 1166 defer m.Unlock() 1167 1168 if m.Path == nil { 1169 m.Path = []string{} 1170 } 1171 if m.Outputs == nil { 1172 m.Outputs = make(map[string]*OutputState) 1173 } 1174 if m.Resources == nil { 1175 m.Resources = make(map[string]*ResourceState) 1176 } 1177 1178 if m.Dependencies == nil { 1179 m.Dependencies = make([]string, 0) 1180 } 1181 1182 for _, rs := range m.Resources { 1183 rs.init() 1184 } 1185 } 1186 1187 func (m *ModuleState) deepcopy() *ModuleState { 1188 if m == nil { 1189 return nil 1190 } 1191 1192 stateCopy, err := copystructure.Config{Lock: true}.Copy(m) 1193 if err != nil { 1194 panic(err) 1195 } 1196 1197 return stateCopy.(*ModuleState) 1198 } 1199 1200 // prune is used to remove any resources that are no longer required 1201 func (m *ModuleState) prune() { 1202 m.Lock() 1203 defer m.Unlock() 1204 1205 for k, v := range m.Resources { 1206 if v == nil || (v.Primary == nil || v.Primary.ID == "") && len(v.Deposed) == 0 { 1207 delete(m.Resources, k) 1208 continue 1209 } 1210 1211 v.prune() 1212 } 1213 1214 for k, v := range m.Outputs { 1215 if v.Value == config.UnknownVariableValue { 1216 delete(m.Outputs, k) 1217 } 1218 } 1219 1220 m.Dependencies = uniqueStrings(m.Dependencies) 1221 } 1222 1223 func (m *ModuleState) sort() { 1224 for _, v := range m.Resources { 1225 v.sort() 1226 } 1227 } 1228 1229 func (m *ModuleState) String() string { 1230 m.Lock() 1231 defer m.Unlock() 1232 1233 var buf bytes.Buffer 1234 1235 if len(m.Resources) == 0 { 1236 buf.WriteString("<no state>") 1237 } 1238 1239 names := make([]string, 0, len(m.Resources)) 1240 for name, _ := range m.Resources { 1241 names = append(names, name) 1242 } 1243 1244 sort.Sort(resourceNameSort(names)) 1245 1246 for _, k := range names { 1247 rs := m.Resources[k] 1248 var id string 1249 if rs.Primary != nil { 1250 id = rs.Primary.ID 1251 } 1252 if id == "" { 1253 id = "<not created>" 1254 } 1255 1256 taintStr := "" 1257 if rs.Primary.Tainted { 1258 taintStr = " (tainted)" 1259 } 1260 1261 deposedStr := "" 1262 if len(rs.Deposed) > 0 { 1263 deposedStr = fmt.Sprintf(" (%d deposed)", len(rs.Deposed)) 1264 } 1265 1266 buf.WriteString(fmt.Sprintf("%s:%s%s\n", k, taintStr, deposedStr)) 1267 buf.WriteString(fmt.Sprintf(" ID = %s\n", id)) 1268 if rs.Provider != "" { 1269 buf.WriteString(fmt.Sprintf(" provider = %s\n", rs.Provider)) 1270 } 1271 1272 var attributes map[string]string 1273 if rs.Primary != nil { 1274 attributes = rs.Primary.Attributes 1275 } 1276 attrKeys := make([]string, 0, len(attributes)) 1277 for ak, _ := range attributes { 1278 if ak == "id" { 1279 continue 1280 } 1281 1282 attrKeys = append(attrKeys, ak) 1283 } 1284 1285 sort.Strings(attrKeys) 1286 1287 for _, ak := range attrKeys { 1288 av := attributes[ak] 1289 buf.WriteString(fmt.Sprintf(" %s = %s\n", ak, av)) 1290 } 1291 1292 for idx, t := range rs.Deposed { 1293 taintStr := "" 1294 if t.Tainted { 1295 taintStr = " (tainted)" 1296 } 1297 buf.WriteString(fmt.Sprintf(" Deposed ID %d = %s%s\n", idx+1, t.ID, taintStr)) 1298 } 1299 1300 if len(rs.Dependencies) > 0 { 1301 buf.WriteString(fmt.Sprintf("\n Dependencies:\n")) 1302 for _, dep := range rs.Dependencies { 1303 buf.WriteString(fmt.Sprintf(" %s\n", dep)) 1304 } 1305 } 1306 } 1307 1308 if len(m.Outputs) > 0 { 1309 buf.WriteString("\nOutputs:\n\n") 1310 1311 ks := make([]string, 0, len(m.Outputs)) 1312 for k, _ := range m.Outputs { 1313 ks = append(ks, k) 1314 } 1315 1316 sort.Strings(ks) 1317 1318 for _, k := range ks { 1319 v := m.Outputs[k] 1320 switch vTyped := v.Value.(type) { 1321 case string: 1322 buf.WriteString(fmt.Sprintf("%s = %s\n", k, vTyped)) 1323 case []interface{}: 1324 buf.WriteString(fmt.Sprintf("%s = %s\n", k, vTyped)) 1325 case map[string]interface{}: 1326 var mapKeys []string 1327 for key, _ := range vTyped { 1328 mapKeys = append(mapKeys, key) 1329 } 1330 sort.Strings(mapKeys) 1331 1332 var mapBuf bytes.Buffer 1333 mapBuf.WriteString("{") 1334 for _, key := range mapKeys { 1335 mapBuf.WriteString(fmt.Sprintf("%s:%s ", key, vTyped[key])) 1336 } 1337 mapBuf.WriteString("}") 1338 1339 buf.WriteString(fmt.Sprintf("%s = %s\n", k, mapBuf.String())) 1340 } 1341 } 1342 } 1343 1344 return buf.String() 1345 } 1346 1347 func (m *ModuleState) Empty() bool { 1348 return len(m.Locals) == 0 && len(m.Outputs) == 0 && len(m.Resources) == 0 1349 } 1350 1351 // ResourceStateKey is a structured representation of the key used for the 1352 // ModuleState.Resources mapping 1353 type ResourceStateKey struct { 1354 Name string 1355 Type string 1356 Mode config.ResourceMode 1357 Index int 1358 } 1359 1360 // Equal determines whether two ResourceStateKeys are the same 1361 func (rsk *ResourceStateKey) Equal(other *ResourceStateKey) bool { 1362 if rsk == nil || other == nil { 1363 return false 1364 } 1365 if rsk.Mode != other.Mode { 1366 return false 1367 } 1368 if rsk.Type != other.Type { 1369 return false 1370 } 1371 if rsk.Name != other.Name { 1372 return false 1373 } 1374 if rsk.Index != other.Index { 1375 return false 1376 } 1377 return true 1378 } 1379 1380 func (rsk *ResourceStateKey) String() string { 1381 if rsk == nil { 1382 return "" 1383 } 1384 var prefix string 1385 switch rsk.Mode { 1386 case config.ManagedResourceMode: 1387 prefix = "" 1388 case config.DataResourceMode: 1389 prefix = "data." 1390 default: 1391 panic(fmt.Errorf("unknown resource mode %s", rsk.Mode)) 1392 } 1393 if rsk.Index == -1 { 1394 return fmt.Sprintf("%s%s.%s", prefix, rsk.Type, rsk.Name) 1395 } 1396 return fmt.Sprintf("%s%s.%s.%d", prefix, rsk.Type, rsk.Name, rsk.Index) 1397 } 1398 1399 // ParseResourceStateKey accepts a key in the format used by 1400 // ModuleState.Resources and returns a resource name and resource index. In the 1401 // state, a resource has the format "type.name.index" or "type.name". In the 1402 // latter case, the index is returned as -1. 1403 func ParseResourceStateKey(k string) (*ResourceStateKey, error) { 1404 parts := strings.Split(k, ".") 1405 mode := config.ManagedResourceMode 1406 if len(parts) > 0 && parts[0] == "data" { 1407 mode = config.DataResourceMode 1408 // Don't need the constant "data" prefix for parsing 1409 // now that we've figured out the mode. 1410 parts = parts[1:] 1411 } 1412 if len(parts) < 2 || len(parts) > 3 { 1413 return nil, fmt.Errorf("Malformed resource state key: %s", k) 1414 } 1415 rsk := &ResourceStateKey{ 1416 Mode: mode, 1417 Type: parts[0], 1418 Name: parts[1], 1419 Index: -1, 1420 } 1421 if len(parts) == 3 { 1422 index, err := strconv.Atoi(parts[2]) 1423 if err != nil { 1424 return nil, fmt.Errorf("Malformed resource state key index: %s", k) 1425 } 1426 rsk.Index = index 1427 } 1428 return rsk, nil 1429 } 1430 1431 // ResourceState holds the state of a resource that is used so that 1432 // a provider can find and manage an existing resource as well as for 1433 // storing attributes that are used to populate variables of child 1434 // resources. 1435 // 1436 // Attributes has attributes about the created resource that are 1437 // queryable in interpolation: "${type.id.attr}" 1438 // 1439 // Extra is just extra data that a provider can return that we store 1440 // for later, but is not exposed in any way to the user. 1441 // 1442 type ResourceState struct { 1443 // This is filled in and managed by Terraform, and is the resource 1444 // type itself such as "mycloud_instance". If a resource provider sets 1445 // this value, it won't be persisted. 1446 Type string `json:"type"` 1447 1448 // Dependencies are a list of things that this resource relies on 1449 // existing to remain intact. For example: an AWS instance might 1450 // depend on a subnet (which itself might depend on a VPC, and so 1451 // on). 1452 // 1453 // Terraform uses this information to build valid destruction 1454 // orders and to warn the user if they're destroying a resource that 1455 // another resource depends on. 1456 // 1457 // Things can be put into this list that may not be managed by 1458 // Terraform. If Terraform doesn't find a matching ID in the 1459 // overall state, then it assumes it isn't managed and doesn't 1460 // worry about it. 1461 Dependencies []string `json:"depends_on"` 1462 1463 // Primary is the current active instance for this resource. 1464 // It can be replaced but only after a successful creation. 1465 // This is the instances on which providers will act. 1466 Primary *InstanceState `json:"primary"` 1467 1468 // Deposed is used in the mechanics of CreateBeforeDestroy: the existing 1469 // Primary is Deposed to get it out of the way for the replacement Primary to 1470 // be created by Apply. If the replacement Primary creates successfully, the 1471 // Deposed instance is cleaned up. 1472 // 1473 // If there were problems creating the replacement Primary, the Deposed 1474 // instance and the (now tainted) replacement Primary will be swapped so the 1475 // tainted replacement will be cleaned up instead. 1476 // 1477 // An instance will remain in the Deposed list until it is successfully 1478 // destroyed and purged. 1479 Deposed []*InstanceState `json:"deposed"` 1480 1481 // Provider is used when a resource is connected to a provider with an alias. 1482 // If this string is empty, the resource is connected to the default provider, 1483 // e.g. "aws_instance" goes with the "aws" provider. 1484 // If the resource block contained a "provider" key, that value will be set here. 1485 Provider string `json:"provider"` 1486 1487 mu sync.Mutex 1488 } 1489 1490 func (s *ResourceState) Lock() { s.mu.Lock() } 1491 func (s *ResourceState) Unlock() { s.mu.Unlock() } 1492 1493 // Equal tests whether two ResourceStates are equal. 1494 func (s *ResourceState) Equal(other *ResourceState) bool { 1495 s.Lock() 1496 defer s.Unlock() 1497 1498 if s.Type != other.Type { 1499 return false 1500 } 1501 1502 if s.Provider != other.Provider { 1503 return false 1504 } 1505 1506 // Dependencies must be equal 1507 sort.Strings(s.Dependencies) 1508 sort.Strings(other.Dependencies) 1509 if len(s.Dependencies) != len(other.Dependencies) { 1510 return false 1511 } 1512 for i, d := range s.Dependencies { 1513 if other.Dependencies[i] != d { 1514 return false 1515 } 1516 } 1517 1518 // States must be equal 1519 if !s.Primary.Equal(other.Primary) { 1520 return false 1521 } 1522 1523 return true 1524 } 1525 1526 // Taint marks a resource as tainted. 1527 func (s *ResourceState) Taint() { 1528 s.Lock() 1529 defer s.Unlock() 1530 1531 if s.Primary != nil { 1532 s.Primary.Tainted = true 1533 } 1534 } 1535 1536 // Untaint unmarks a resource as tainted. 1537 func (s *ResourceState) Untaint() { 1538 s.Lock() 1539 defer s.Unlock() 1540 1541 if s.Primary != nil { 1542 s.Primary.Tainted = false 1543 } 1544 } 1545 1546 func (s *ResourceState) init() { 1547 s.Lock() 1548 defer s.Unlock() 1549 1550 if s.Primary == nil { 1551 s.Primary = &InstanceState{} 1552 } 1553 s.Primary.init() 1554 1555 if s.Dependencies == nil { 1556 s.Dependencies = []string{} 1557 } 1558 1559 if s.Deposed == nil { 1560 s.Deposed = make([]*InstanceState, 0) 1561 } 1562 } 1563 1564 func (s *ResourceState) deepcopy() *ResourceState { 1565 copy, err := copystructure.Config{Lock: true}.Copy(s) 1566 if err != nil { 1567 panic(err) 1568 } 1569 1570 return copy.(*ResourceState) 1571 } 1572 1573 // prune is used to remove any instances that are no longer required 1574 func (s *ResourceState) prune() { 1575 s.Lock() 1576 defer s.Unlock() 1577 1578 n := len(s.Deposed) 1579 for i := 0; i < n; i++ { 1580 inst := s.Deposed[i] 1581 if inst == nil || inst.ID == "" { 1582 copy(s.Deposed[i:], s.Deposed[i+1:]) 1583 s.Deposed[n-1] = nil 1584 n-- 1585 i-- 1586 } 1587 } 1588 s.Deposed = s.Deposed[:n] 1589 1590 s.Dependencies = uniqueStrings(s.Dependencies) 1591 } 1592 1593 func (s *ResourceState) sort() { 1594 s.Lock() 1595 defer s.Unlock() 1596 1597 sort.Strings(s.Dependencies) 1598 } 1599 1600 func (s *ResourceState) String() string { 1601 s.Lock() 1602 defer s.Unlock() 1603 1604 var buf bytes.Buffer 1605 buf.WriteString(fmt.Sprintf("Type = %s", s.Type)) 1606 return buf.String() 1607 } 1608 1609 // InstanceState is used to track the unique state information belonging 1610 // to a given instance. 1611 type InstanceState struct { 1612 // A unique ID for this resource. This is opaque to Terraform 1613 // and is only meant as a lookup mechanism for the providers. 1614 ID string `json:"id"` 1615 1616 // Attributes are basic information about the resource. Any keys here 1617 // are accessible in variable format within Terraform configurations: 1618 // ${resourcetype.name.attribute}. 1619 Attributes map[string]string `json:"attributes"` 1620 1621 // Ephemeral is used to store any state associated with this instance 1622 // that is necessary for the Terraform run to complete, but is not 1623 // persisted to a state file. 1624 Ephemeral EphemeralState `json:"-"` 1625 1626 // Meta is a simple K/V map that is persisted to the State but otherwise 1627 // ignored by Terraform core. It's meant to be used for accounting by 1628 // external client code. The value here must only contain Go primitives 1629 // and collections. 1630 Meta map[string]interface{} `json:"meta"` 1631 1632 // Tainted is used to mark a resource for recreation. 1633 Tainted bool `json:"tainted"` 1634 1635 mu sync.Mutex 1636 } 1637 1638 func (s *InstanceState) Lock() { s.mu.Lock() } 1639 func (s *InstanceState) Unlock() { s.mu.Unlock() } 1640 1641 func (s *InstanceState) init() { 1642 s.Lock() 1643 defer s.Unlock() 1644 1645 if s.Attributes == nil { 1646 s.Attributes = make(map[string]string) 1647 } 1648 if s.Meta == nil { 1649 s.Meta = make(map[string]interface{}) 1650 } 1651 s.Ephemeral.init() 1652 } 1653 1654 // Copy all the Fields from another InstanceState 1655 func (s *InstanceState) Set(from *InstanceState) { 1656 s.Lock() 1657 defer s.Unlock() 1658 1659 from.Lock() 1660 defer from.Unlock() 1661 1662 s.ID = from.ID 1663 s.Attributes = from.Attributes 1664 s.Ephemeral = from.Ephemeral 1665 s.Meta = from.Meta 1666 s.Tainted = from.Tainted 1667 } 1668 1669 func (s *InstanceState) DeepCopy() *InstanceState { 1670 copy, err := copystructure.Config{Lock: true}.Copy(s) 1671 if err != nil { 1672 panic(err) 1673 } 1674 1675 return copy.(*InstanceState) 1676 } 1677 1678 func (s *InstanceState) Empty() bool { 1679 if s == nil { 1680 return true 1681 } 1682 s.Lock() 1683 defer s.Unlock() 1684 1685 return s.ID == "" 1686 } 1687 1688 func (s *InstanceState) Equal(other *InstanceState) bool { 1689 // Short circuit some nil checks 1690 if s == nil || other == nil { 1691 return s == other 1692 } 1693 s.Lock() 1694 defer s.Unlock() 1695 1696 // IDs must be equal 1697 if s.ID != other.ID { 1698 return false 1699 } 1700 1701 // Attributes must be equal 1702 if len(s.Attributes) != len(other.Attributes) { 1703 return false 1704 } 1705 for k, v := range s.Attributes { 1706 otherV, ok := other.Attributes[k] 1707 if !ok { 1708 return false 1709 } 1710 1711 if v != otherV { 1712 return false 1713 } 1714 } 1715 1716 // Meta must be equal 1717 if len(s.Meta) != len(other.Meta) { 1718 return false 1719 } 1720 if s.Meta != nil && other.Meta != nil { 1721 // We only do the deep check if both are non-nil. If one is nil 1722 // we treat it as equal since their lengths are both zero (check 1723 // above). 1724 // 1725 // Since this can contain numeric values that may change types during 1726 // serialization, let's compare the serialized values. 1727 sMeta, err := json.Marshal(s.Meta) 1728 if err != nil { 1729 // marshaling primitives shouldn't ever error out 1730 panic(err) 1731 } 1732 otherMeta, err := json.Marshal(other.Meta) 1733 if err != nil { 1734 panic(err) 1735 } 1736 1737 if !bytes.Equal(sMeta, otherMeta) { 1738 return false 1739 } 1740 } 1741 1742 if s.Tainted != other.Tainted { 1743 return false 1744 } 1745 1746 return true 1747 } 1748 1749 // MergeDiff takes a ResourceDiff and merges the attributes into 1750 // this resource state in order to generate a new state. This new 1751 // state can be used to provide updated attribute lookups for 1752 // variable interpolation. 1753 // 1754 // If the diff attribute requires computing the value, and hence 1755 // won't be available until apply, the value is replaced with the 1756 // computeID. 1757 func (s *InstanceState) MergeDiff(d *InstanceDiff) *InstanceState { 1758 result := s.DeepCopy() 1759 if result == nil { 1760 result = new(InstanceState) 1761 } 1762 result.init() 1763 1764 if s != nil { 1765 s.Lock() 1766 defer s.Unlock() 1767 for k, v := range s.Attributes { 1768 result.Attributes[k] = v 1769 } 1770 } 1771 if d != nil { 1772 for k, diff := range d.CopyAttributes() { 1773 if diff.NewRemoved { 1774 delete(result.Attributes, k) 1775 continue 1776 } 1777 if diff.NewComputed { 1778 result.Attributes[k] = config.UnknownVariableValue 1779 continue 1780 } 1781 1782 result.Attributes[k] = diff.New 1783 } 1784 } 1785 1786 return result 1787 } 1788 1789 func (s *InstanceState) String() string { 1790 s.Lock() 1791 defer s.Unlock() 1792 1793 var buf bytes.Buffer 1794 1795 if s == nil || s.ID == "" { 1796 return "<not created>" 1797 } 1798 1799 buf.WriteString(fmt.Sprintf("ID = %s\n", s.ID)) 1800 1801 attributes := s.Attributes 1802 attrKeys := make([]string, 0, len(attributes)) 1803 for ak, _ := range attributes { 1804 if ak == "id" { 1805 continue 1806 } 1807 1808 attrKeys = append(attrKeys, ak) 1809 } 1810 sort.Strings(attrKeys) 1811 1812 for _, ak := range attrKeys { 1813 av := attributes[ak] 1814 buf.WriteString(fmt.Sprintf("%s = %s\n", ak, av)) 1815 } 1816 1817 buf.WriteString(fmt.Sprintf("Tainted = %t\n", s.Tainted)) 1818 1819 return buf.String() 1820 } 1821 1822 // EphemeralState is used for transient state that is only kept in-memory 1823 type EphemeralState struct { 1824 // ConnInfo is used for the providers to export information which is 1825 // used to connect to the resource for provisioning. For example, 1826 // this could contain SSH or WinRM credentials. 1827 ConnInfo map[string]string `json:"-"` 1828 1829 // Type is used to specify the resource type for this instance. This is only 1830 // required for import operations (as documented). If the documentation 1831 // doesn't state that you need to set this, then don't worry about 1832 // setting it. 1833 Type string `json:"-"` 1834 } 1835 1836 func (e *EphemeralState) init() { 1837 if e.ConnInfo == nil { 1838 e.ConnInfo = make(map[string]string) 1839 } 1840 } 1841 1842 func (e *EphemeralState) DeepCopy() *EphemeralState { 1843 copy, err := copystructure.Config{Lock: true}.Copy(e) 1844 if err != nil { 1845 panic(err) 1846 } 1847 1848 return copy.(*EphemeralState) 1849 } 1850 1851 type jsonStateVersionIdentifier struct { 1852 Version int `json:"version"` 1853 } 1854 1855 // Check if this is a V0 format - the magic bytes at the start of the file 1856 // should be "tfstate" if so. We no longer support upgrading this type of 1857 // state but return an error message explaining to a user how they can 1858 // upgrade via the 0.6.x series. 1859 func testForV0State(buf *bufio.Reader) error { 1860 start, err := buf.Peek(len("tfstate")) 1861 if err != nil { 1862 return fmt.Errorf("Failed to check for magic bytes: %v", err) 1863 } 1864 if string(start) == "tfstate" { 1865 return fmt.Errorf("Terraform 0.7 no longer supports upgrading the binary state\n" + 1866 "format which was used prior to Terraform 0.3. Please upgrade\n" + 1867 "this state file using Terraform 0.6.16 prior to using it with\n" + 1868 "Terraform 0.7.") 1869 } 1870 1871 return nil 1872 } 1873 1874 // ErrNoState is returned by ReadState when the io.Reader contains no data 1875 var ErrNoState = errors.New("no state") 1876 1877 // ReadState reads a state structure out of a reader in the format that 1878 // was written by WriteState. 1879 func ReadState(src io.Reader) (*State, error) { 1880 // check for a nil file specifically, since that produces a platform 1881 // specific error if we try to use it in a bufio.Reader. 1882 if f, ok := src.(*os.File); ok && f == nil { 1883 return nil, ErrNoState 1884 } 1885 1886 buf := bufio.NewReader(src) 1887 1888 if _, err := buf.Peek(1); err != nil { 1889 if err == io.EOF { 1890 return nil, ErrNoState 1891 } 1892 return nil, err 1893 } 1894 1895 if err := testForV0State(buf); err != nil { 1896 return nil, err 1897 } 1898 1899 // If we are JSON we buffer the whole thing in memory so we can read it twice. 1900 // This is suboptimal, but will work for now. 1901 jsonBytes, err := ioutil.ReadAll(buf) 1902 if err != nil { 1903 return nil, fmt.Errorf("Reading state file failed: %v", err) 1904 } 1905 1906 versionIdentifier := &jsonStateVersionIdentifier{} 1907 if err := json.Unmarshal(jsonBytes, versionIdentifier); err != nil { 1908 return nil, fmt.Errorf("Decoding state file version failed: %v", err) 1909 } 1910 1911 var result *State 1912 switch versionIdentifier.Version { 1913 case 0: 1914 return nil, fmt.Errorf("State version 0 is not supported as JSON.") 1915 case 1: 1916 v1State, err := ReadStateV1(jsonBytes) 1917 if err != nil { 1918 return nil, err 1919 } 1920 1921 v2State, err := upgradeStateV1ToV2(v1State) 1922 if err != nil { 1923 return nil, err 1924 } 1925 1926 v3State, err := upgradeStateV2ToV3(v2State) 1927 if err != nil { 1928 return nil, err 1929 } 1930 1931 // increment the Serial whenever we upgrade state 1932 v3State.Serial++ 1933 result = v3State 1934 case 2: 1935 v2State, err := ReadStateV2(jsonBytes) 1936 if err != nil { 1937 return nil, err 1938 } 1939 v3State, err := upgradeStateV2ToV3(v2State) 1940 if err != nil { 1941 return nil, err 1942 } 1943 1944 v3State.Serial++ 1945 result = v3State 1946 case 3: 1947 v3State, err := ReadStateV3(jsonBytes) 1948 if err != nil { 1949 return nil, err 1950 } 1951 1952 result = v3State 1953 default: 1954 return nil, fmt.Errorf("Terraform %s does not support state version %d, please update.", 1955 tfversion.SemVer.String(), versionIdentifier.Version) 1956 } 1957 1958 // If we reached this place we must have a result set 1959 if result == nil { 1960 panic("resulting state in load not set, assertion failed") 1961 } 1962 1963 // Prune the state when read it. Its possible to write unpruned states or 1964 // for a user to make a state unpruned (nil-ing a module state for example). 1965 result.prune() 1966 1967 // Validate the state file is valid 1968 if err := result.Validate(); err != nil { 1969 return nil, err 1970 } 1971 1972 return result, nil 1973 } 1974 1975 func ReadStateV1(jsonBytes []byte) (*stateV1, error) { 1976 v1State := &stateV1{} 1977 if err := json.Unmarshal(jsonBytes, v1State); err != nil { 1978 return nil, fmt.Errorf("Decoding state file failed: %v", err) 1979 } 1980 1981 if v1State.Version != 1 { 1982 return nil, fmt.Errorf("Decoded state version did not match the decoder selection: "+ 1983 "read %d, expected 1", v1State.Version) 1984 } 1985 1986 return v1State, nil 1987 } 1988 1989 func ReadStateV2(jsonBytes []byte) (*State, error) { 1990 state := &State{} 1991 if err := json.Unmarshal(jsonBytes, state); err != nil { 1992 return nil, fmt.Errorf("Decoding state file failed: %v", err) 1993 } 1994 1995 // Check the version, this to ensure we don't read a future 1996 // version that we don't understand 1997 if state.Version > StateVersion { 1998 return nil, fmt.Errorf("Terraform %s does not support state version %d, please update.", 1999 tfversion.SemVer.String(), state.Version) 2000 } 2001 2002 // Make sure the version is semantic 2003 if state.TFVersion != "" { 2004 if _, err := version.NewVersion(state.TFVersion); err != nil { 2005 return nil, fmt.Errorf( 2006 "State contains invalid version: %s\n\n"+ 2007 "Terraform validates the version format prior to writing it. This\n"+ 2008 "means that this is invalid of the state becoming corrupted through\n"+ 2009 "some external means. Please manually modify the Terraform version\n"+ 2010 "field to be a proper semantic version.", 2011 state.TFVersion) 2012 } 2013 } 2014 2015 // catch any unitialized fields in the state 2016 state.init() 2017 2018 // Sort it 2019 state.sort() 2020 2021 return state, nil 2022 } 2023 2024 func ReadStateV3(jsonBytes []byte) (*State, error) { 2025 state := &State{} 2026 if err := json.Unmarshal(jsonBytes, state); err != nil { 2027 return nil, fmt.Errorf("Decoding state file failed: %v", err) 2028 } 2029 2030 // Check the version, this to ensure we don't read a future 2031 // version that we don't understand 2032 if state.Version > StateVersion { 2033 return nil, fmt.Errorf("Terraform %s does not support state version %d, please update.", 2034 tfversion.SemVer.String(), state.Version) 2035 } 2036 2037 // Make sure the version is semantic 2038 if state.TFVersion != "" { 2039 if _, err := version.NewVersion(state.TFVersion); err != nil { 2040 return nil, fmt.Errorf( 2041 "State contains invalid version: %s\n\n"+ 2042 "Terraform validates the version format prior to writing it. This\n"+ 2043 "means that this is invalid of the state becoming corrupted through\n"+ 2044 "some external means. Please manually modify the Terraform version\n"+ 2045 "field to be a proper semantic version.", 2046 state.TFVersion) 2047 } 2048 } 2049 2050 // catch any unitialized fields in the state 2051 state.init() 2052 2053 // Sort it 2054 state.sort() 2055 2056 // Now we write the state back out to detect any changes in normaliztion. 2057 // If our state is now written out differently, bump the serial number to 2058 // prevent conflicts. 2059 var buf bytes.Buffer 2060 err := WriteState(state, &buf) 2061 if err != nil { 2062 return nil, err 2063 } 2064 2065 if !bytes.Equal(jsonBytes, buf.Bytes()) { 2066 log.Println("[INFO] state modified during read or write. incrementing serial number") 2067 state.Serial++ 2068 } 2069 2070 return state, nil 2071 } 2072 2073 // WriteState writes a state somewhere in a binary format. 2074 func WriteState(d *State, dst io.Writer) error { 2075 // writing a nil state is a noop. 2076 if d == nil { 2077 return nil 2078 } 2079 2080 // make sure we have no uninitialized fields 2081 d.init() 2082 2083 // Make sure it is sorted 2084 d.sort() 2085 2086 // Ensure the version is set 2087 d.Version = StateVersion 2088 2089 // If the TFVersion is set, verify it. We used to just set the version 2090 // here, but this isn't safe since it changes the MD5 sum on some remote 2091 // state storage backends such as Atlas. We now leave it be if needed. 2092 if d.TFVersion != "" { 2093 if _, err := version.NewVersion(d.TFVersion); err != nil { 2094 return fmt.Errorf( 2095 "Error writing state, invalid version: %s\n\n"+ 2096 "The Terraform version when writing the state must be a semantic\n"+ 2097 "version.", 2098 d.TFVersion) 2099 } 2100 } 2101 2102 // Encode the data in a human-friendly way 2103 data, err := json.MarshalIndent(d, "", " ") 2104 if err != nil { 2105 return fmt.Errorf("Failed to encode state: %s", err) 2106 } 2107 2108 // We append a newline to the data because MarshalIndent doesn't 2109 data = append(data, '\n') 2110 2111 // Write the data out to the dst 2112 if _, err := io.Copy(dst, bytes.NewReader(data)); err != nil { 2113 return fmt.Errorf("Failed to write state: %v", err) 2114 } 2115 2116 return nil 2117 } 2118 2119 // resourceNameSort implements the sort.Interface to sort name parts lexically for 2120 // strings and numerically for integer indexes. 2121 type resourceNameSort []string 2122 2123 func (r resourceNameSort) Len() int { return len(r) } 2124 func (r resourceNameSort) Swap(i, j int) { r[i], r[j] = r[j], r[i] } 2125 2126 func (r resourceNameSort) Less(i, j int) bool { 2127 iParts := strings.Split(r[i], ".") 2128 jParts := strings.Split(r[j], ".") 2129 2130 end := len(iParts) 2131 if len(jParts) < end { 2132 end = len(jParts) 2133 } 2134 2135 for idx := 0; idx < end; idx++ { 2136 if iParts[idx] == jParts[idx] { 2137 continue 2138 } 2139 2140 // sort on the first non-matching part 2141 iInt, iIntErr := strconv.Atoi(iParts[idx]) 2142 jInt, jIntErr := strconv.Atoi(jParts[idx]) 2143 2144 switch { 2145 case iIntErr == nil && jIntErr == nil: 2146 // sort numerically if both parts are integers 2147 return iInt < jInt 2148 case iIntErr == nil: 2149 // numbers sort before strings 2150 return true 2151 case jIntErr == nil: 2152 return false 2153 default: 2154 return iParts[idx] < jParts[idx] 2155 } 2156 } 2157 2158 return r[i] < r[j] 2159 } 2160 2161 // moduleStateSort implements sort.Interface to sort module states 2162 type moduleStateSort []*ModuleState 2163 2164 func (s moduleStateSort) Len() int { 2165 return len(s) 2166 } 2167 2168 func (s moduleStateSort) Less(i, j int) bool { 2169 a := s[i] 2170 b := s[j] 2171 2172 // If either is nil, then the nil one is "less" than 2173 if a == nil || b == nil { 2174 return a == nil 2175 } 2176 2177 // If the lengths are different, then the shorter one always wins 2178 if len(a.Path) != len(b.Path) { 2179 return len(a.Path) < len(b.Path) 2180 } 2181 2182 // Otherwise, compare lexically 2183 return strings.Join(a.Path, ".") < strings.Join(b.Path, ".") 2184 } 2185 2186 func (s moduleStateSort) Swap(i, j int) { 2187 s[i], s[j] = s[j], s[i] 2188 } 2189 2190 // StateCompatible returns an error if the state is not compatible with the 2191 // current version of terraform. 2192 func CheckStateVersion(state *State) error { 2193 if state == nil { 2194 return nil 2195 } 2196 2197 if state.FromFutureTerraform() { 2198 return fmt.Errorf(stateInvalidTerraformVersionErr, state.TFVersion) 2199 } 2200 return nil 2201 } 2202 2203 const stateValidateErrMultiModule = ` 2204 Multiple modules with the same path: %s 2205 2206 This means that there are multiple entries in the "modules" field 2207 in your state file that point to the same module. This will cause Terraform 2208 to behave in unexpected and error prone ways and is invalid. Please back up 2209 and modify your state file manually to resolve this. 2210 ` 2211 2212 const stateInvalidTerraformVersionErr = ` 2213 Terraform doesn't allow running any operations against a state 2214 that was written by a future Terraform version. The state is 2215 reporting it is written by Terraform '%s' 2216 2217 Please run at least that version of Terraform to continue. 2218 `