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