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