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