github.com/chentex/terraform@v0.11.2-0.20171208003256-252e8145842e/terraform/state.go (about) 1 package terraform 2 3 import ( 4 "bufio" 5 "bytes" 6 "encoding/json" 7 "errors" 8 "fmt" 9 "io" 10 "io/ioutil" 11 "log" 12 "reflect" 13 "sort" 14 "strconv" 15 "strings" 16 "sync" 17 18 "github.com/hashicorp/go-multierror" 19 "github.com/hashicorp/go-version" 20 "github.com/hashicorp/terraform/config" 21 "github.com/mitchellh/copystructure" 22 "github.com/satori/go.uuid" 23 24 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 s.Lineage = uuid.NewV4().String() 710 log.Printf("[DEBUG] New state was assigned lineage %q\n", s.Lineage) 711 } else { 712 log.Printf("[TRACE] Preserving existing state lineage %q\n", s.Lineage) 713 } 714 } 715 716 // AddModuleState insert this module state and override any existing ModuleState 717 func (s *State) AddModuleState(mod *ModuleState) { 718 mod.init() 719 s.Lock() 720 defer s.Unlock() 721 722 s.addModuleState(mod) 723 } 724 725 func (s *State) addModuleState(mod *ModuleState) { 726 for i, m := range s.Modules { 727 if reflect.DeepEqual(m.Path, mod.Path) { 728 s.Modules[i] = mod 729 return 730 } 731 } 732 733 s.Modules = append(s.Modules, mod) 734 s.sort() 735 } 736 737 // prune is used to remove any resources that are no longer required 738 func (s *State) prune() { 739 if s == nil { 740 return 741 } 742 743 // Filter out empty modules. 744 // A module is always assumed to have a path, and it's length isn't always 745 // bounds checked later on. Modules may be "emptied" during destroy, but we 746 // never want to store those in the state. 747 for i := 0; i < len(s.Modules); i++ { 748 if s.Modules[i] == nil || len(s.Modules[i].Path) == 0 { 749 s.Modules = append(s.Modules[:i], s.Modules[i+1:]...) 750 i-- 751 } 752 } 753 754 for _, mod := range s.Modules { 755 mod.prune() 756 } 757 if s.Remote != nil && s.Remote.Empty() { 758 s.Remote = nil 759 } 760 } 761 762 // sort sorts the modules 763 func (s *State) sort() { 764 sort.Sort(moduleStateSort(s.Modules)) 765 766 // Allow modules to be sorted 767 for _, m := range s.Modules { 768 if m != nil { 769 m.sort() 770 } 771 } 772 } 773 774 func (s *State) String() string { 775 if s == nil { 776 return "<nil>" 777 } 778 s.Lock() 779 defer s.Unlock() 780 781 var buf bytes.Buffer 782 for _, m := range s.Modules { 783 mStr := m.String() 784 785 // If we're the root module, we just write the output directly. 786 if reflect.DeepEqual(m.Path, rootModulePath) { 787 buf.WriteString(mStr + "\n") 788 continue 789 } 790 791 buf.WriteString(fmt.Sprintf("module.%s:\n", strings.Join(m.Path[1:], "."))) 792 793 s := bufio.NewScanner(strings.NewReader(mStr)) 794 for s.Scan() { 795 text := s.Text() 796 if text != "" { 797 text = " " + text 798 } 799 800 buf.WriteString(fmt.Sprintf("%s\n", text)) 801 } 802 } 803 804 return strings.TrimSpace(buf.String()) 805 } 806 807 // BackendState stores the configuration to connect to a remote backend. 808 type BackendState struct { 809 Type string `json:"type"` // Backend type 810 Config map[string]interface{} `json:"config"` // Backend raw config 811 812 // Hash is the hash code to uniquely identify the original source 813 // configuration. We use this to detect when there is a change in 814 // configuration even when "type" isn't changed. 815 Hash uint64 `json:"hash"` 816 } 817 818 // Empty returns true if BackendState has no state. 819 func (s *BackendState) Empty() bool { 820 return s == nil || s.Type == "" 821 } 822 823 // Rehash returns a unique content hash for this backend's configuration 824 // as a uint64 value. 825 // The Hash stored in the backend state needs to match the config itself, but 826 // we need to compare the backend config after it has been combined with all 827 // options. 828 // This function must match the implementation used by config.Backend. 829 func (s *BackendState) Rehash() uint64 { 830 if s == nil { 831 return 0 832 } 833 834 cfg := config.Backend{ 835 Type: s.Type, 836 RawConfig: &config.RawConfig{ 837 Raw: s.Config, 838 }, 839 } 840 841 return cfg.Rehash() 842 } 843 844 // RemoteState is used to track the information about a remote 845 // state store that we push/pull state to. 846 type RemoteState struct { 847 // Type controls the client we use for the remote state 848 Type string `json:"type"` 849 850 // Config is used to store arbitrary configuration that 851 // is type specific 852 Config map[string]string `json:"config"` 853 854 mu sync.Mutex 855 } 856 857 func (s *RemoteState) Lock() { s.mu.Lock() } 858 func (s *RemoteState) Unlock() { s.mu.Unlock() } 859 860 func (r *RemoteState) init() { 861 r.Lock() 862 defer r.Unlock() 863 864 if r.Config == nil { 865 r.Config = make(map[string]string) 866 } 867 } 868 869 func (r *RemoteState) deepcopy() *RemoteState { 870 r.Lock() 871 defer r.Unlock() 872 873 confCopy := make(map[string]string, len(r.Config)) 874 for k, v := range r.Config { 875 confCopy[k] = v 876 } 877 return &RemoteState{ 878 Type: r.Type, 879 Config: confCopy, 880 } 881 } 882 883 func (r *RemoteState) Empty() bool { 884 if r == nil { 885 return true 886 } 887 r.Lock() 888 defer r.Unlock() 889 890 return r.Type == "" 891 } 892 893 func (r *RemoteState) Equals(other *RemoteState) bool { 894 r.Lock() 895 defer r.Unlock() 896 897 if r.Type != other.Type { 898 return false 899 } 900 if len(r.Config) != len(other.Config) { 901 return false 902 } 903 for k, v := range r.Config { 904 if other.Config[k] != v { 905 return false 906 } 907 } 908 return true 909 } 910 911 // OutputState is used to track the state relevant to a single output. 912 type OutputState struct { 913 // Sensitive describes whether the output is considered sensitive, 914 // which may lead to masking the value on screen in some cases. 915 Sensitive bool `json:"sensitive"` 916 // Type describes the structure of Value. Valid values are "string", 917 // "map" and "list" 918 Type string `json:"type"` 919 // Value contains the value of the output, in the structure described 920 // by the Type field. 921 Value interface{} `json:"value"` 922 923 mu sync.Mutex 924 } 925 926 func (s *OutputState) Lock() { s.mu.Lock() } 927 func (s *OutputState) Unlock() { s.mu.Unlock() } 928 929 func (s *OutputState) String() string { 930 return fmt.Sprintf("%#v", s.Value) 931 } 932 933 // Equal compares two OutputState structures for equality. nil values are 934 // considered equal. 935 func (s *OutputState) Equal(other *OutputState) bool { 936 if s == nil && other == nil { 937 return true 938 } 939 940 if s == nil || other == nil { 941 return false 942 } 943 s.Lock() 944 defer s.Unlock() 945 946 if s.Type != other.Type { 947 return false 948 } 949 950 if s.Sensitive != other.Sensitive { 951 return false 952 } 953 954 if !reflect.DeepEqual(s.Value, other.Value) { 955 return false 956 } 957 958 return true 959 } 960 961 func (s *OutputState) deepcopy() *OutputState { 962 if s == nil { 963 return nil 964 } 965 966 stateCopy, err := copystructure.Config{Lock: true}.Copy(s) 967 if err != nil { 968 panic(fmt.Errorf("Error copying output value: %s", err)) 969 } 970 971 return stateCopy.(*OutputState) 972 } 973 974 // ModuleState is used to track all the state relevant to a single 975 // module. Previous to Terraform 0.3, all state belonged to the "root" 976 // module. 977 type ModuleState struct { 978 // Path is the import path from the root module. Modules imports are 979 // always disjoint, so the path represents amodule tree 980 Path []string `json:"path"` 981 982 // Locals are kept only transiently in-memory, because we can always 983 // re-compute them. 984 Locals map[string]interface{} `json:"-"` 985 986 // Outputs declared by the module and maintained for each module 987 // even though only the root module technically needs to be kept. 988 // This allows operators to inspect values at the boundaries. 989 Outputs map[string]*OutputState `json:"outputs"` 990 991 // Resources is a mapping of the logically named resource to 992 // the state of the resource. Each resource may actually have 993 // N instances underneath, although a user only needs to think 994 // about the 1:1 case. 995 Resources map[string]*ResourceState `json:"resources"` 996 997 // Dependencies are a list of things that this module relies on 998 // existing to remain intact. For example: an module may depend 999 // on a VPC ID given by an aws_vpc resource. 1000 // 1001 // Terraform uses this information to build valid destruction 1002 // orders and to warn the user if they're destroying a module that 1003 // another resource depends on. 1004 // 1005 // Things can be put into this list that may not be managed by 1006 // Terraform. If Terraform doesn't find a matching ID in the 1007 // overall state, then it assumes it isn't managed and doesn't 1008 // worry about it. 1009 Dependencies []string `json:"depends_on"` 1010 1011 mu sync.Mutex 1012 } 1013 1014 func (s *ModuleState) Lock() { s.mu.Lock() } 1015 func (s *ModuleState) Unlock() { s.mu.Unlock() } 1016 1017 // Equal tests whether one module state is equal to another. 1018 func (m *ModuleState) Equal(other *ModuleState) bool { 1019 m.Lock() 1020 defer m.Unlock() 1021 1022 // Paths must be equal 1023 if !reflect.DeepEqual(m.Path, other.Path) { 1024 return false 1025 } 1026 1027 // Outputs must be equal 1028 if len(m.Outputs) != len(other.Outputs) { 1029 return false 1030 } 1031 for k, v := range m.Outputs { 1032 if !other.Outputs[k].Equal(v) { 1033 return false 1034 } 1035 } 1036 1037 // Dependencies must be equal. This sorts these in place but 1038 // this shouldn't cause any problems. 1039 sort.Strings(m.Dependencies) 1040 sort.Strings(other.Dependencies) 1041 if len(m.Dependencies) != len(other.Dependencies) { 1042 return false 1043 } 1044 for i, d := range m.Dependencies { 1045 if other.Dependencies[i] != d { 1046 return false 1047 } 1048 } 1049 1050 // Resources must be equal 1051 if len(m.Resources) != len(other.Resources) { 1052 return false 1053 } 1054 for k, r := range m.Resources { 1055 otherR, ok := other.Resources[k] 1056 if !ok { 1057 return false 1058 } 1059 1060 if !r.Equal(otherR) { 1061 return false 1062 } 1063 } 1064 1065 return true 1066 } 1067 1068 // IsRoot says whether or not this module diff is for the root module. 1069 func (m *ModuleState) IsRoot() bool { 1070 m.Lock() 1071 defer m.Unlock() 1072 return reflect.DeepEqual(m.Path, rootModulePath) 1073 } 1074 1075 // IsDescendent returns true if other is a descendent of this module. 1076 func (m *ModuleState) IsDescendent(other *ModuleState) bool { 1077 m.Lock() 1078 defer m.Unlock() 1079 1080 i := len(m.Path) 1081 return len(other.Path) > i && reflect.DeepEqual(other.Path[:i], m.Path) 1082 } 1083 1084 // Orphans returns a list of keys of resources that are in the State 1085 // but aren't present in the configuration itself. Hence, these keys 1086 // represent the state of resources that are orphans. 1087 func (m *ModuleState) Orphans(c *config.Config) []string { 1088 m.Lock() 1089 defer m.Unlock() 1090 1091 keys := make(map[string]struct{}) 1092 for k := range m.Resources { 1093 keys[k] = struct{}{} 1094 } 1095 1096 if c != nil { 1097 for _, r := range c.Resources { 1098 delete(keys, r.Id()) 1099 1100 for k := range keys { 1101 if strings.HasPrefix(k, r.Id()+".") { 1102 delete(keys, k) 1103 } 1104 } 1105 } 1106 } 1107 1108 result := make([]string, 0, len(keys)) 1109 for k := range keys { 1110 result = append(result, k) 1111 } 1112 1113 return result 1114 } 1115 1116 // RemovedOutputs returns a list of outputs that are in the State but aren't 1117 // present in the configuration itself. 1118 func (m *ModuleState) RemovedOutputs(c *config.Config) []string { 1119 m.Lock() 1120 defer m.Unlock() 1121 1122 keys := make(map[string]struct{}) 1123 for k := range m.Outputs { 1124 keys[k] = struct{}{} 1125 } 1126 1127 if c != nil { 1128 for _, o := range c.Outputs { 1129 delete(keys, o.Name) 1130 } 1131 } 1132 1133 result := make([]string, 0, len(keys)) 1134 for k := range keys { 1135 result = append(result, k) 1136 } 1137 1138 return result 1139 } 1140 1141 // View returns a view with the given resource prefix. 1142 func (m *ModuleState) View(id string) *ModuleState { 1143 if m == nil { 1144 return m 1145 } 1146 1147 r := m.deepcopy() 1148 for k, _ := range r.Resources { 1149 if id == k || strings.HasPrefix(k, id+".") { 1150 continue 1151 } 1152 1153 delete(r.Resources, k) 1154 } 1155 1156 return r 1157 } 1158 1159 func (m *ModuleState) init() { 1160 m.Lock() 1161 defer m.Unlock() 1162 1163 if m.Path == nil { 1164 m.Path = []string{} 1165 } 1166 if m.Outputs == nil { 1167 m.Outputs = make(map[string]*OutputState) 1168 } 1169 if m.Resources == nil { 1170 m.Resources = make(map[string]*ResourceState) 1171 } 1172 1173 if m.Dependencies == nil { 1174 m.Dependencies = make([]string, 0) 1175 } 1176 1177 for _, rs := range m.Resources { 1178 rs.init() 1179 } 1180 } 1181 1182 func (m *ModuleState) deepcopy() *ModuleState { 1183 if m == nil { 1184 return nil 1185 } 1186 1187 stateCopy, err := copystructure.Config{Lock: true}.Copy(m) 1188 if err != nil { 1189 panic(err) 1190 } 1191 1192 return stateCopy.(*ModuleState) 1193 } 1194 1195 // prune is used to remove any resources that are no longer required 1196 func (m *ModuleState) prune() { 1197 m.Lock() 1198 defer m.Unlock() 1199 1200 for k, v := range m.Resources { 1201 if v == nil || (v.Primary == nil || v.Primary.ID == "") && len(v.Deposed) == 0 { 1202 delete(m.Resources, k) 1203 continue 1204 } 1205 1206 v.prune() 1207 } 1208 1209 for k, v := range m.Outputs { 1210 if v.Value == config.UnknownVariableValue { 1211 delete(m.Outputs, k) 1212 } 1213 } 1214 1215 m.Dependencies = uniqueStrings(m.Dependencies) 1216 } 1217 1218 func (m *ModuleState) sort() { 1219 for _, v := range m.Resources { 1220 v.sort() 1221 } 1222 } 1223 1224 func (m *ModuleState) String() string { 1225 m.Lock() 1226 defer m.Unlock() 1227 1228 var buf bytes.Buffer 1229 1230 if len(m.Resources) == 0 { 1231 buf.WriteString("<no state>") 1232 } 1233 1234 names := make([]string, 0, len(m.Resources)) 1235 for name, _ := range m.Resources { 1236 names = append(names, name) 1237 } 1238 1239 sort.Sort(resourceNameSort(names)) 1240 1241 for _, k := range names { 1242 rs := m.Resources[k] 1243 var id string 1244 if rs.Primary != nil { 1245 id = rs.Primary.ID 1246 } 1247 if id == "" { 1248 id = "<not created>" 1249 } 1250 1251 taintStr := "" 1252 if rs.Primary.Tainted { 1253 taintStr = " (tainted)" 1254 } 1255 1256 deposedStr := "" 1257 if len(rs.Deposed) > 0 { 1258 deposedStr = fmt.Sprintf(" (%d deposed)", len(rs.Deposed)) 1259 } 1260 1261 buf.WriteString(fmt.Sprintf("%s:%s%s\n", k, taintStr, deposedStr)) 1262 buf.WriteString(fmt.Sprintf(" ID = %s\n", id)) 1263 if rs.Provider != "" { 1264 buf.WriteString(fmt.Sprintf(" provider = %s\n", rs.Provider)) 1265 } 1266 1267 var attributes map[string]string 1268 if rs.Primary != nil { 1269 attributes = rs.Primary.Attributes 1270 } 1271 attrKeys := make([]string, 0, len(attributes)) 1272 for ak, _ := range attributes { 1273 if ak == "id" { 1274 continue 1275 } 1276 1277 attrKeys = append(attrKeys, ak) 1278 } 1279 1280 sort.Strings(attrKeys) 1281 1282 for _, ak := range attrKeys { 1283 av := attributes[ak] 1284 buf.WriteString(fmt.Sprintf(" %s = %s\n", ak, av)) 1285 } 1286 1287 for idx, t := range rs.Deposed { 1288 taintStr := "" 1289 if t.Tainted { 1290 taintStr = " (tainted)" 1291 } 1292 buf.WriteString(fmt.Sprintf(" Deposed ID %d = %s%s\n", idx+1, t.ID, taintStr)) 1293 } 1294 1295 if len(rs.Dependencies) > 0 { 1296 buf.WriteString(fmt.Sprintf("\n Dependencies:\n")) 1297 for _, dep := range rs.Dependencies { 1298 buf.WriteString(fmt.Sprintf(" %s\n", dep)) 1299 } 1300 } 1301 } 1302 1303 if len(m.Outputs) > 0 { 1304 buf.WriteString("\nOutputs:\n\n") 1305 1306 ks := make([]string, 0, len(m.Outputs)) 1307 for k, _ := range m.Outputs { 1308 ks = append(ks, k) 1309 } 1310 1311 sort.Strings(ks) 1312 1313 for _, k := range ks { 1314 v := m.Outputs[k] 1315 switch vTyped := v.Value.(type) { 1316 case string: 1317 buf.WriteString(fmt.Sprintf("%s = %s\n", k, vTyped)) 1318 case []interface{}: 1319 buf.WriteString(fmt.Sprintf("%s = %s\n", k, vTyped)) 1320 case map[string]interface{}: 1321 var mapKeys []string 1322 for key, _ := range vTyped { 1323 mapKeys = append(mapKeys, key) 1324 } 1325 sort.Strings(mapKeys) 1326 1327 var mapBuf bytes.Buffer 1328 mapBuf.WriteString("{") 1329 for _, key := range mapKeys { 1330 mapBuf.WriteString(fmt.Sprintf("%s:%s ", key, vTyped[key])) 1331 } 1332 mapBuf.WriteString("}") 1333 1334 buf.WriteString(fmt.Sprintf("%s = %s\n", k, mapBuf.String())) 1335 } 1336 } 1337 } 1338 1339 return buf.String() 1340 } 1341 1342 func (m *ModuleState) Empty() bool { 1343 return len(m.Locals) == 0 && len(m.Outputs) == 0 && len(m.Resources) == 0 1344 } 1345 1346 // ResourceStateKey is a structured representation of the key used for the 1347 // ModuleState.Resources mapping 1348 type ResourceStateKey struct { 1349 Name string 1350 Type string 1351 Mode config.ResourceMode 1352 Index int 1353 } 1354 1355 // Equal determines whether two ResourceStateKeys are the same 1356 func (rsk *ResourceStateKey) Equal(other *ResourceStateKey) bool { 1357 if rsk == nil || other == nil { 1358 return false 1359 } 1360 if rsk.Mode != other.Mode { 1361 return false 1362 } 1363 if rsk.Type != other.Type { 1364 return false 1365 } 1366 if rsk.Name != other.Name { 1367 return false 1368 } 1369 if rsk.Index != other.Index { 1370 return false 1371 } 1372 return true 1373 } 1374 1375 func (rsk *ResourceStateKey) String() string { 1376 if rsk == nil { 1377 return "" 1378 } 1379 var prefix string 1380 switch rsk.Mode { 1381 case config.ManagedResourceMode: 1382 prefix = "" 1383 case config.DataResourceMode: 1384 prefix = "data." 1385 default: 1386 panic(fmt.Errorf("unknown resource mode %s", rsk.Mode)) 1387 } 1388 if rsk.Index == -1 { 1389 return fmt.Sprintf("%s%s.%s", prefix, rsk.Type, rsk.Name) 1390 } 1391 return fmt.Sprintf("%s%s.%s.%d", prefix, rsk.Type, rsk.Name, rsk.Index) 1392 } 1393 1394 // ParseResourceStateKey accepts a key in the format used by 1395 // ModuleState.Resources and returns a resource name and resource index. In the 1396 // state, a resource has the format "type.name.index" or "type.name". In the 1397 // latter case, the index is returned as -1. 1398 func ParseResourceStateKey(k string) (*ResourceStateKey, error) { 1399 parts := strings.Split(k, ".") 1400 mode := config.ManagedResourceMode 1401 if len(parts) > 0 && parts[0] == "data" { 1402 mode = config.DataResourceMode 1403 // Don't need the constant "data" prefix for parsing 1404 // now that we've figured out the mode. 1405 parts = parts[1:] 1406 } 1407 if len(parts) < 2 || len(parts) > 3 { 1408 return nil, fmt.Errorf("Malformed resource state key: %s", k) 1409 } 1410 rsk := &ResourceStateKey{ 1411 Mode: mode, 1412 Type: parts[0], 1413 Name: parts[1], 1414 Index: -1, 1415 } 1416 if len(parts) == 3 { 1417 index, err := strconv.Atoi(parts[2]) 1418 if err != nil { 1419 return nil, fmt.Errorf("Malformed resource state key index: %s", k) 1420 } 1421 rsk.Index = index 1422 } 1423 return rsk, nil 1424 } 1425 1426 // ResourceState holds the state of a resource that is used so that 1427 // a provider can find and manage an existing resource as well as for 1428 // storing attributes that are used to populate variables of child 1429 // resources. 1430 // 1431 // Attributes has attributes about the created resource that are 1432 // queryable in interpolation: "${type.id.attr}" 1433 // 1434 // Extra is just extra data that a provider can return that we store 1435 // for later, but is not exposed in any way to the user. 1436 // 1437 type ResourceState struct { 1438 // This is filled in and managed by Terraform, and is the resource 1439 // type itself such as "mycloud_instance". If a resource provider sets 1440 // this value, it won't be persisted. 1441 Type string `json:"type"` 1442 1443 // Dependencies are a list of things that this resource relies on 1444 // existing to remain intact. For example: an AWS instance might 1445 // depend on a subnet (which itself might depend on a VPC, and so 1446 // on). 1447 // 1448 // Terraform uses this information to build valid destruction 1449 // orders and to warn the user if they're destroying a resource that 1450 // another resource depends on. 1451 // 1452 // Things can be put into this list that may not be managed by 1453 // Terraform. If Terraform doesn't find a matching ID in the 1454 // overall state, then it assumes it isn't managed and doesn't 1455 // worry about it. 1456 Dependencies []string `json:"depends_on"` 1457 1458 // Primary is the current active instance for this resource. 1459 // It can be replaced but only after a successful creation. 1460 // This is the instances on which providers will act. 1461 Primary *InstanceState `json:"primary"` 1462 1463 // Deposed is used in the mechanics of CreateBeforeDestroy: the existing 1464 // Primary is Deposed to get it out of the way for the replacement Primary to 1465 // be created by Apply. If the replacement Primary creates successfully, the 1466 // Deposed instance is cleaned up. 1467 // 1468 // If there were problems creating the replacement Primary, the Deposed 1469 // instance and the (now tainted) replacement Primary will be swapped so the 1470 // tainted replacement will be cleaned up instead. 1471 // 1472 // An instance will remain in the Deposed list until it is successfully 1473 // destroyed and purged. 1474 Deposed []*InstanceState `json:"deposed"` 1475 1476 // Provider is used when a resource is connected to a provider with an alias. 1477 // If this string is empty, the resource is connected to the default provider, 1478 // e.g. "aws_instance" goes with the "aws" provider. 1479 // If the resource block contained a "provider" key, that value will be set here. 1480 Provider string `json:"provider"` 1481 1482 mu sync.Mutex 1483 } 1484 1485 func (s *ResourceState) Lock() { s.mu.Lock() } 1486 func (s *ResourceState) Unlock() { s.mu.Unlock() } 1487 1488 // Equal tests whether two ResourceStates are equal. 1489 func (s *ResourceState) Equal(other *ResourceState) bool { 1490 s.Lock() 1491 defer s.Unlock() 1492 1493 if s.Type != other.Type { 1494 return false 1495 } 1496 1497 if s.Provider != other.Provider { 1498 return false 1499 } 1500 1501 // Dependencies must be equal 1502 sort.Strings(s.Dependencies) 1503 sort.Strings(other.Dependencies) 1504 if len(s.Dependencies) != len(other.Dependencies) { 1505 return false 1506 } 1507 for i, d := range s.Dependencies { 1508 if other.Dependencies[i] != d { 1509 return false 1510 } 1511 } 1512 1513 // States must be equal 1514 if !s.Primary.Equal(other.Primary) { 1515 return false 1516 } 1517 1518 return true 1519 } 1520 1521 // Taint marks a resource as tainted. 1522 func (s *ResourceState) Taint() { 1523 s.Lock() 1524 defer s.Unlock() 1525 1526 if s.Primary != nil { 1527 s.Primary.Tainted = true 1528 } 1529 } 1530 1531 // Untaint unmarks a resource as tainted. 1532 func (s *ResourceState) Untaint() { 1533 s.Lock() 1534 defer s.Unlock() 1535 1536 if s.Primary != nil { 1537 s.Primary.Tainted = false 1538 } 1539 } 1540 1541 func (s *ResourceState) init() { 1542 s.Lock() 1543 defer s.Unlock() 1544 1545 if s.Primary == nil { 1546 s.Primary = &InstanceState{} 1547 } 1548 s.Primary.init() 1549 1550 if s.Dependencies == nil { 1551 s.Dependencies = []string{} 1552 } 1553 1554 if s.Deposed == nil { 1555 s.Deposed = make([]*InstanceState, 0) 1556 } 1557 } 1558 1559 func (s *ResourceState) deepcopy() *ResourceState { 1560 copy, err := copystructure.Config{Lock: true}.Copy(s) 1561 if err != nil { 1562 panic(err) 1563 } 1564 1565 return copy.(*ResourceState) 1566 } 1567 1568 // prune is used to remove any instances that are no longer required 1569 func (s *ResourceState) prune() { 1570 s.Lock() 1571 defer s.Unlock() 1572 1573 n := len(s.Deposed) 1574 for i := 0; i < n; i++ { 1575 inst := s.Deposed[i] 1576 if inst == nil || inst.ID == "" { 1577 copy(s.Deposed[i:], s.Deposed[i+1:]) 1578 s.Deposed[n-1] = nil 1579 n-- 1580 i-- 1581 } 1582 } 1583 s.Deposed = s.Deposed[:n] 1584 1585 s.Dependencies = uniqueStrings(s.Dependencies) 1586 } 1587 1588 func (s *ResourceState) sort() { 1589 s.Lock() 1590 defer s.Unlock() 1591 1592 sort.Strings(s.Dependencies) 1593 } 1594 1595 func (s *ResourceState) String() string { 1596 s.Lock() 1597 defer s.Unlock() 1598 1599 var buf bytes.Buffer 1600 buf.WriteString(fmt.Sprintf("Type = %s", s.Type)) 1601 return buf.String() 1602 } 1603 1604 // InstanceState is used to track the unique state information belonging 1605 // to a given instance. 1606 type InstanceState struct { 1607 // A unique ID for this resource. This is opaque to Terraform 1608 // and is only meant as a lookup mechanism for the providers. 1609 ID string `json:"id"` 1610 1611 // Attributes are basic information about the resource. Any keys here 1612 // are accessible in variable format within Terraform configurations: 1613 // ${resourcetype.name.attribute}. 1614 Attributes map[string]string `json:"attributes"` 1615 1616 // Ephemeral is used to store any state associated with this instance 1617 // that is necessary for the Terraform run to complete, but is not 1618 // persisted to a state file. 1619 Ephemeral EphemeralState `json:"-"` 1620 1621 // Meta is a simple K/V map that is persisted to the State but otherwise 1622 // ignored by Terraform core. It's meant to be used for accounting by 1623 // external client code. The value here must only contain Go primitives 1624 // and collections. 1625 Meta map[string]interface{} `json:"meta"` 1626 1627 // Tainted is used to mark a resource for recreation. 1628 Tainted bool `json:"tainted"` 1629 1630 mu sync.Mutex 1631 } 1632 1633 func (s *InstanceState) Lock() { s.mu.Lock() } 1634 func (s *InstanceState) Unlock() { s.mu.Unlock() } 1635 1636 func (s *InstanceState) init() { 1637 s.Lock() 1638 defer s.Unlock() 1639 1640 if s.Attributes == nil { 1641 s.Attributes = make(map[string]string) 1642 } 1643 if s.Meta == nil { 1644 s.Meta = make(map[string]interface{}) 1645 } 1646 s.Ephemeral.init() 1647 } 1648 1649 // Copy all the Fields from another InstanceState 1650 func (s *InstanceState) Set(from *InstanceState) { 1651 s.Lock() 1652 defer s.Unlock() 1653 1654 from.Lock() 1655 defer from.Unlock() 1656 1657 s.ID = from.ID 1658 s.Attributes = from.Attributes 1659 s.Ephemeral = from.Ephemeral 1660 s.Meta = from.Meta 1661 s.Tainted = from.Tainted 1662 } 1663 1664 func (s *InstanceState) DeepCopy() *InstanceState { 1665 copy, err := copystructure.Config{Lock: true}.Copy(s) 1666 if err != nil { 1667 panic(err) 1668 } 1669 1670 return copy.(*InstanceState) 1671 } 1672 1673 func (s *InstanceState) Empty() bool { 1674 if s == nil { 1675 return true 1676 } 1677 s.Lock() 1678 defer s.Unlock() 1679 1680 return s.ID == "" 1681 } 1682 1683 func (s *InstanceState) Equal(other *InstanceState) bool { 1684 // Short circuit some nil checks 1685 if s == nil || other == nil { 1686 return s == other 1687 } 1688 s.Lock() 1689 defer s.Unlock() 1690 1691 // IDs must be equal 1692 if s.ID != other.ID { 1693 return false 1694 } 1695 1696 // Attributes must be equal 1697 if len(s.Attributes) != len(other.Attributes) { 1698 return false 1699 } 1700 for k, v := range s.Attributes { 1701 otherV, ok := other.Attributes[k] 1702 if !ok { 1703 return false 1704 } 1705 1706 if v != otherV { 1707 return false 1708 } 1709 } 1710 1711 // Meta must be equal 1712 if len(s.Meta) != len(other.Meta) { 1713 return false 1714 } 1715 if s.Meta != nil && other.Meta != nil { 1716 // We only do the deep check if both are non-nil. If one is nil 1717 // we treat it as equal since their lengths are both zero (check 1718 // above). 1719 // 1720 // Since this can contain numeric values that may change types during 1721 // serialization, let's compare the serialized values. 1722 sMeta, err := json.Marshal(s.Meta) 1723 if err != nil { 1724 // marshaling primitives shouldn't ever error out 1725 panic(err) 1726 } 1727 otherMeta, err := json.Marshal(other.Meta) 1728 if err != nil { 1729 panic(err) 1730 } 1731 1732 if !bytes.Equal(sMeta, otherMeta) { 1733 return false 1734 } 1735 } 1736 1737 if s.Tainted != other.Tainted { 1738 return false 1739 } 1740 1741 return true 1742 } 1743 1744 // MergeDiff takes a ResourceDiff and merges the attributes into 1745 // this resource state in order to generate a new state. This new 1746 // state can be used to provide updated attribute lookups for 1747 // variable interpolation. 1748 // 1749 // If the diff attribute requires computing the value, and hence 1750 // won't be available until apply, the value is replaced with the 1751 // computeID. 1752 func (s *InstanceState) MergeDiff(d *InstanceDiff) *InstanceState { 1753 result := s.DeepCopy() 1754 if result == nil { 1755 result = new(InstanceState) 1756 } 1757 result.init() 1758 1759 if s != nil { 1760 s.Lock() 1761 defer s.Unlock() 1762 for k, v := range s.Attributes { 1763 result.Attributes[k] = v 1764 } 1765 } 1766 if d != nil { 1767 for k, diff := range d.CopyAttributes() { 1768 if diff.NewRemoved { 1769 delete(result.Attributes, k) 1770 continue 1771 } 1772 if diff.NewComputed { 1773 result.Attributes[k] = config.UnknownVariableValue 1774 continue 1775 } 1776 1777 result.Attributes[k] = diff.New 1778 } 1779 } 1780 1781 return result 1782 } 1783 1784 func (s *InstanceState) String() string { 1785 s.Lock() 1786 defer s.Unlock() 1787 1788 var buf bytes.Buffer 1789 1790 if s == nil || s.ID == "" { 1791 return "<not created>" 1792 } 1793 1794 buf.WriteString(fmt.Sprintf("ID = %s\n", s.ID)) 1795 1796 attributes := s.Attributes 1797 attrKeys := make([]string, 0, len(attributes)) 1798 for ak, _ := range attributes { 1799 if ak == "id" { 1800 continue 1801 } 1802 1803 attrKeys = append(attrKeys, ak) 1804 } 1805 sort.Strings(attrKeys) 1806 1807 for _, ak := range attrKeys { 1808 av := attributes[ak] 1809 buf.WriteString(fmt.Sprintf("%s = %s\n", ak, av)) 1810 } 1811 1812 buf.WriteString(fmt.Sprintf("Tainted = %t\n", s.Tainted)) 1813 1814 return buf.String() 1815 } 1816 1817 // EphemeralState is used for transient state that is only kept in-memory 1818 type EphemeralState struct { 1819 // ConnInfo is used for the providers to export information which is 1820 // used to connect to the resource for provisioning. For example, 1821 // this could contain SSH or WinRM credentials. 1822 ConnInfo map[string]string `json:"-"` 1823 1824 // Type is used to specify the resource type for this instance. This is only 1825 // required for import operations (as documented). If the documentation 1826 // doesn't state that you need to set this, then don't worry about 1827 // setting it. 1828 Type string `json:"-"` 1829 } 1830 1831 func (e *EphemeralState) init() { 1832 if e.ConnInfo == nil { 1833 e.ConnInfo = make(map[string]string) 1834 } 1835 } 1836 1837 func (e *EphemeralState) DeepCopy() *EphemeralState { 1838 copy, err := copystructure.Config{Lock: true}.Copy(e) 1839 if err != nil { 1840 panic(err) 1841 } 1842 1843 return copy.(*EphemeralState) 1844 } 1845 1846 type jsonStateVersionIdentifier struct { 1847 Version int `json:"version"` 1848 } 1849 1850 // Check if this is a V0 format - the magic bytes at the start of the file 1851 // should be "tfstate" if so. We no longer support upgrading this type of 1852 // state but return an error message explaining to a user how they can 1853 // upgrade via the 0.6.x series. 1854 func testForV0State(buf *bufio.Reader) error { 1855 start, err := buf.Peek(len("tfstate")) 1856 if err != nil { 1857 return fmt.Errorf("Failed to check for magic bytes: %v", err) 1858 } 1859 if string(start) == "tfstate" { 1860 return fmt.Errorf("Terraform 0.7 no longer supports upgrading the binary state\n" + 1861 "format which was used prior to Terraform 0.3. Please upgrade\n" + 1862 "this state file using Terraform 0.6.16 prior to using it with\n" + 1863 "Terraform 0.7.") 1864 } 1865 1866 return nil 1867 } 1868 1869 // ErrNoState is returned by ReadState when the io.Reader contains no data 1870 var ErrNoState = errors.New("no state") 1871 1872 // ReadState reads a state structure out of a reader in the format that 1873 // was written by WriteState. 1874 func ReadState(src io.Reader) (*State, error) { 1875 buf := bufio.NewReader(src) 1876 if _, err := buf.Peek(1); err != nil { 1877 // the error is either io.EOF or "invalid argument", and both are from 1878 // an empty state. 1879 return nil, ErrNoState 1880 } 1881 1882 if err := testForV0State(buf); err != nil { 1883 return nil, err 1884 } 1885 1886 // If we are JSON we buffer the whole thing in memory so we can read it twice. 1887 // This is suboptimal, but will work for now. 1888 jsonBytes, err := ioutil.ReadAll(buf) 1889 if err != nil { 1890 return nil, fmt.Errorf("Reading state file failed: %v", err) 1891 } 1892 1893 versionIdentifier := &jsonStateVersionIdentifier{} 1894 if err := json.Unmarshal(jsonBytes, versionIdentifier); err != nil { 1895 return nil, fmt.Errorf("Decoding state file version failed: %v", err) 1896 } 1897 1898 var result *State 1899 switch versionIdentifier.Version { 1900 case 0: 1901 return nil, fmt.Errorf("State version 0 is not supported as JSON.") 1902 case 1: 1903 v1State, err := ReadStateV1(jsonBytes) 1904 if err != nil { 1905 return nil, err 1906 } 1907 1908 v2State, err := upgradeStateV1ToV2(v1State) 1909 if err != nil { 1910 return nil, err 1911 } 1912 1913 v3State, err := upgradeStateV2ToV3(v2State) 1914 if err != nil { 1915 return nil, err 1916 } 1917 1918 // increment the Serial whenever we upgrade state 1919 v3State.Serial++ 1920 result = v3State 1921 case 2: 1922 v2State, err := ReadStateV2(jsonBytes) 1923 if err != nil { 1924 return nil, err 1925 } 1926 v3State, err := upgradeStateV2ToV3(v2State) 1927 if err != nil { 1928 return nil, err 1929 } 1930 1931 v3State.Serial++ 1932 result = v3State 1933 case 3: 1934 v3State, err := ReadStateV3(jsonBytes) 1935 if err != nil { 1936 return nil, err 1937 } 1938 1939 result = v3State 1940 default: 1941 return nil, fmt.Errorf("Terraform %s does not support state version %d, please update.", 1942 tfversion.SemVer.String(), versionIdentifier.Version) 1943 } 1944 1945 // If we reached this place we must have a result set 1946 if result == nil { 1947 panic("resulting state in load not set, assertion failed") 1948 } 1949 1950 // Prune the state when read it. Its possible to write unpruned states or 1951 // for a user to make a state unpruned (nil-ing a module state for example). 1952 result.prune() 1953 1954 // Validate the state file is valid 1955 if err := result.Validate(); err != nil { 1956 return nil, err 1957 } 1958 1959 return result, nil 1960 } 1961 1962 func ReadStateV1(jsonBytes []byte) (*stateV1, error) { 1963 v1State := &stateV1{} 1964 if err := json.Unmarshal(jsonBytes, v1State); err != nil { 1965 return nil, fmt.Errorf("Decoding state file failed: %v", err) 1966 } 1967 1968 if v1State.Version != 1 { 1969 return nil, fmt.Errorf("Decoded state version did not match the decoder selection: "+ 1970 "read %d, expected 1", v1State.Version) 1971 } 1972 1973 return v1State, nil 1974 } 1975 1976 func ReadStateV2(jsonBytes []byte) (*State, error) { 1977 state := &State{} 1978 if err := json.Unmarshal(jsonBytes, state); err != nil { 1979 return nil, fmt.Errorf("Decoding state file failed: %v", err) 1980 } 1981 1982 // Check the version, this to ensure we don't read a future 1983 // version that we don't understand 1984 if state.Version > StateVersion { 1985 return nil, fmt.Errorf("Terraform %s does not support state version %d, please update.", 1986 tfversion.SemVer.String(), state.Version) 1987 } 1988 1989 // Make sure the version is semantic 1990 if state.TFVersion != "" { 1991 if _, err := version.NewVersion(state.TFVersion); err != nil { 1992 return nil, fmt.Errorf( 1993 "State contains invalid version: %s\n\n"+ 1994 "Terraform validates the version format prior to writing it. This\n"+ 1995 "means that this is invalid of the state becoming corrupted through\n"+ 1996 "some external means. Please manually modify the Terraform version\n"+ 1997 "field to be a proper semantic version.", 1998 state.TFVersion) 1999 } 2000 } 2001 2002 // catch any unitialized fields in the state 2003 state.init() 2004 2005 // Sort it 2006 state.sort() 2007 2008 return state, nil 2009 } 2010 2011 func ReadStateV3(jsonBytes []byte) (*State, error) { 2012 state := &State{} 2013 if err := json.Unmarshal(jsonBytes, state); err != nil { 2014 return nil, fmt.Errorf("Decoding state file failed: %v", err) 2015 } 2016 2017 // Check the version, this to ensure we don't read a future 2018 // version that we don't understand 2019 if state.Version > StateVersion { 2020 return nil, fmt.Errorf("Terraform %s does not support state version %d, please update.", 2021 tfversion.SemVer.String(), state.Version) 2022 } 2023 2024 // Make sure the version is semantic 2025 if state.TFVersion != "" { 2026 if _, err := version.NewVersion(state.TFVersion); err != nil { 2027 return nil, fmt.Errorf( 2028 "State contains invalid version: %s\n\n"+ 2029 "Terraform validates the version format prior to writing it. This\n"+ 2030 "means that this is invalid of the state becoming corrupted through\n"+ 2031 "some external means. Please manually modify the Terraform version\n"+ 2032 "field to be a proper semantic version.", 2033 state.TFVersion) 2034 } 2035 } 2036 2037 // catch any unitialized fields in the state 2038 state.init() 2039 2040 // Sort it 2041 state.sort() 2042 2043 // Now we write the state back out to detect any changes in normaliztion. 2044 // If our state is now written out differently, bump the serial number to 2045 // prevent conflicts. 2046 var buf bytes.Buffer 2047 err := WriteState(state, &buf) 2048 if err != nil { 2049 return nil, err 2050 } 2051 2052 if !bytes.Equal(jsonBytes, buf.Bytes()) { 2053 log.Println("[INFO] state modified during read or write. incrementing serial number") 2054 state.Serial++ 2055 } 2056 2057 return state, nil 2058 } 2059 2060 // WriteState writes a state somewhere in a binary format. 2061 func WriteState(d *State, dst io.Writer) error { 2062 // writing a nil state is a noop. 2063 if d == nil { 2064 return nil 2065 } 2066 2067 // make sure we have no uninitialized fields 2068 d.init() 2069 2070 // Make sure it is sorted 2071 d.sort() 2072 2073 // Ensure the version is set 2074 d.Version = StateVersion 2075 2076 // If the TFVersion is set, verify it. We used to just set the version 2077 // here, but this isn't safe since it changes the MD5 sum on some remote 2078 // state storage backends such as Atlas. We now leave it be if needed. 2079 if d.TFVersion != "" { 2080 if _, err := version.NewVersion(d.TFVersion); err != nil { 2081 return fmt.Errorf( 2082 "Error writing state, invalid version: %s\n\n"+ 2083 "The Terraform version when writing the state must be a semantic\n"+ 2084 "version.", 2085 d.TFVersion) 2086 } 2087 } 2088 2089 // Encode the data in a human-friendly way 2090 data, err := json.MarshalIndent(d, "", " ") 2091 if err != nil { 2092 return fmt.Errorf("Failed to encode state: %s", err) 2093 } 2094 2095 // We append a newline to the data because MarshalIndent doesn't 2096 data = append(data, '\n') 2097 2098 // Write the data out to the dst 2099 if _, err := io.Copy(dst, bytes.NewReader(data)); err != nil { 2100 return fmt.Errorf("Failed to write state: %v", err) 2101 } 2102 2103 return nil 2104 } 2105 2106 // resourceNameSort implements the sort.Interface to sort name parts lexically for 2107 // strings and numerically for integer indexes. 2108 type resourceNameSort []string 2109 2110 func (r resourceNameSort) Len() int { return len(r) } 2111 func (r resourceNameSort) Swap(i, j int) { r[i], r[j] = r[j], r[i] } 2112 2113 func (r resourceNameSort) Less(i, j int) bool { 2114 iParts := strings.Split(r[i], ".") 2115 jParts := strings.Split(r[j], ".") 2116 2117 end := len(iParts) 2118 if len(jParts) < end { 2119 end = len(jParts) 2120 } 2121 2122 for idx := 0; idx < end; idx++ { 2123 if iParts[idx] == jParts[idx] { 2124 continue 2125 } 2126 2127 // sort on the first non-matching part 2128 iInt, iIntErr := strconv.Atoi(iParts[idx]) 2129 jInt, jIntErr := strconv.Atoi(jParts[idx]) 2130 2131 switch { 2132 case iIntErr == nil && jIntErr == nil: 2133 // sort numerically if both parts are integers 2134 return iInt < jInt 2135 case iIntErr == nil: 2136 // numbers sort before strings 2137 return true 2138 case jIntErr == nil: 2139 return false 2140 default: 2141 return iParts[idx] < jParts[idx] 2142 } 2143 } 2144 2145 return r[i] < r[j] 2146 } 2147 2148 // moduleStateSort implements sort.Interface to sort module states 2149 type moduleStateSort []*ModuleState 2150 2151 func (s moduleStateSort) Len() int { 2152 return len(s) 2153 } 2154 2155 func (s moduleStateSort) Less(i, j int) bool { 2156 a := s[i] 2157 b := s[j] 2158 2159 // If either is nil, then the nil one is "less" than 2160 if a == nil || b == nil { 2161 return a == nil 2162 } 2163 2164 // If the lengths are different, then the shorter one always wins 2165 if len(a.Path) != len(b.Path) { 2166 return len(a.Path) < len(b.Path) 2167 } 2168 2169 // Otherwise, compare lexically 2170 return strings.Join(a.Path, ".") < strings.Join(b.Path, ".") 2171 } 2172 2173 func (s moduleStateSort) Swap(i, j int) { 2174 s[i], s[j] = s[j], s[i] 2175 } 2176 2177 const stateValidateErrMultiModule = ` 2178 Multiple modules with the same path: %s 2179 2180 This means that there are multiple entries in the "modules" field 2181 in your state file that point to the same module. This will cause Terraform 2182 to behave in unexpected and error prone ways and is invalid. Please back up 2183 and modify your state file manually to resolve this. 2184 `