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