github.com/trawler/terraform@v0.10.8-0.20171106022149-4b1c7a1d9b48/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 // View returns a view with the given resource prefix. 1117 func (m *ModuleState) View(id string) *ModuleState { 1118 if m == nil { 1119 return m 1120 } 1121 1122 r := m.deepcopy() 1123 for k, _ := range r.Resources { 1124 if id == k || strings.HasPrefix(k, id+".") { 1125 continue 1126 } 1127 1128 delete(r.Resources, k) 1129 } 1130 1131 return r 1132 } 1133 1134 func (m *ModuleState) init() { 1135 m.Lock() 1136 defer m.Unlock() 1137 1138 if m.Path == nil { 1139 m.Path = []string{} 1140 } 1141 if m.Outputs == nil { 1142 m.Outputs = make(map[string]*OutputState) 1143 } 1144 if m.Resources == nil { 1145 m.Resources = make(map[string]*ResourceState) 1146 } 1147 1148 if m.Dependencies == nil { 1149 m.Dependencies = make([]string, 0) 1150 } 1151 1152 for _, rs := range m.Resources { 1153 rs.init() 1154 } 1155 } 1156 1157 func (m *ModuleState) deepcopy() *ModuleState { 1158 if m == nil { 1159 return nil 1160 } 1161 1162 stateCopy, err := copystructure.Config{Lock: true}.Copy(m) 1163 if err != nil { 1164 panic(err) 1165 } 1166 1167 return stateCopy.(*ModuleState) 1168 } 1169 1170 // prune is used to remove any resources that are no longer required 1171 func (m *ModuleState) prune() { 1172 m.Lock() 1173 defer m.Unlock() 1174 1175 for k, v := range m.Resources { 1176 if v == nil || (v.Primary == nil || v.Primary.ID == "") && len(v.Deposed) == 0 { 1177 delete(m.Resources, k) 1178 continue 1179 } 1180 1181 v.prune() 1182 } 1183 1184 for k, v := range m.Outputs { 1185 if v.Value == config.UnknownVariableValue { 1186 delete(m.Outputs, k) 1187 } 1188 } 1189 1190 m.Dependencies = uniqueStrings(m.Dependencies) 1191 } 1192 1193 func (m *ModuleState) sort() { 1194 for _, v := range m.Resources { 1195 v.sort() 1196 } 1197 } 1198 1199 func (m *ModuleState) String() string { 1200 m.Lock() 1201 defer m.Unlock() 1202 1203 var buf bytes.Buffer 1204 1205 if len(m.Resources) == 0 { 1206 buf.WriteString("<no state>") 1207 } 1208 1209 names := make([]string, 0, len(m.Resources)) 1210 for name, _ := range m.Resources { 1211 names = append(names, name) 1212 } 1213 1214 sort.Sort(resourceNameSort(names)) 1215 1216 for _, k := range names { 1217 rs := m.Resources[k] 1218 var id string 1219 if rs.Primary != nil { 1220 id = rs.Primary.ID 1221 } 1222 if id == "" { 1223 id = "<not created>" 1224 } 1225 1226 taintStr := "" 1227 if rs.Primary.Tainted { 1228 taintStr = " (tainted)" 1229 } 1230 1231 deposedStr := "" 1232 if len(rs.Deposed) > 0 { 1233 deposedStr = fmt.Sprintf(" (%d deposed)", len(rs.Deposed)) 1234 } 1235 1236 buf.WriteString(fmt.Sprintf("%s:%s%s\n", k, taintStr, deposedStr)) 1237 buf.WriteString(fmt.Sprintf(" ID = %s\n", id)) 1238 if rs.Provider != "" { 1239 buf.WriteString(fmt.Sprintf(" provider = %s\n", rs.Provider)) 1240 } 1241 1242 var attributes map[string]string 1243 if rs.Primary != nil { 1244 attributes = rs.Primary.Attributes 1245 } 1246 attrKeys := make([]string, 0, len(attributes)) 1247 for ak, _ := range attributes { 1248 if ak == "id" { 1249 continue 1250 } 1251 1252 attrKeys = append(attrKeys, ak) 1253 } 1254 1255 sort.Strings(attrKeys) 1256 1257 for _, ak := range attrKeys { 1258 av := attributes[ak] 1259 buf.WriteString(fmt.Sprintf(" %s = %s\n", ak, av)) 1260 } 1261 1262 for idx, t := range rs.Deposed { 1263 taintStr := "" 1264 if t.Tainted { 1265 taintStr = " (tainted)" 1266 } 1267 buf.WriteString(fmt.Sprintf(" Deposed ID %d = %s%s\n", idx+1, t.ID, taintStr)) 1268 } 1269 1270 if len(rs.Dependencies) > 0 { 1271 buf.WriteString(fmt.Sprintf("\n Dependencies:\n")) 1272 for _, dep := range rs.Dependencies { 1273 buf.WriteString(fmt.Sprintf(" %s\n", dep)) 1274 } 1275 } 1276 } 1277 1278 if len(m.Outputs) > 0 { 1279 buf.WriteString("\nOutputs:\n\n") 1280 1281 ks := make([]string, 0, len(m.Outputs)) 1282 for k, _ := range m.Outputs { 1283 ks = append(ks, k) 1284 } 1285 1286 sort.Strings(ks) 1287 1288 for _, k := range ks { 1289 v := m.Outputs[k] 1290 switch vTyped := v.Value.(type) { 1291 case string: 1292 buf.WriteString(fmt.Sprintf("%s = %s\n", k, vTyped)) 1293 case []interface{}: 1294 buf.WriteString(fmt.Sprintf("%s = %s\n", k, vTyped)) 1295 case map[string]interface{}: 1296 var mapKeys []string 1297 for key, _ := range vTyped { 1298 mapKeys = append(mapKeys, key) 1299 } 1300 sort.Strings(mapKeys) 1301 1302 var mapBuf bytes.Buffer 1303 mapBuf.WriteString("{") 1304 for _, key := range mapKeys { 1305 mapBuf.WriteString(fmt.Sprintf("%s:%s ", key, vTyped[key])) 1306 } 1307 mapBuf.WriteString("}") 1308 1309 buf.WriteString(fmt.Sprintf("%s = %s\n", k, mapBuf.String())) 1310 } 1311 } 1312 } 1313 1314 return buf.String() 1315 } 1316 1317 // ResourceStateKey is a structured representation of the key used for the 1318 // ModuleState.Resources mapping 1319 type ResourceStateKey struct { 1320 Name string 1321 Type string 1322 Mode config.ResourceMode 1323 Index int 1324 } 1325 1326 // Equal determines whether two ResourceStateKeys are the same 1327 func (rsk *ResourceStateKey) Equal(other *ResourceStateKey) bool { 1328 if rsk == nil || other == nil { 1329 return false 1330 } 1331 if rsk.Mode != other.Mode { 1332 return false 1333 } 1334 if rsk.Type != other.Type { 1335 return false 1336 } 1337 if rsk.Name != other.Name { 1338 return false 1339 } 1340 if rsk.Index != other.Index { 1341 return false 1342 } 1343 return true 1344 } 1345 1346 func (rsk *ResourceStateKey) String() string { 1347 if rsk == nil { 1348 return "" 1349 } 1350 var prefix string 1351 switch rsk.Mode { 1352 case config.ManagedResourceMode: 1353 prefix = "" 1354 case config.DataResourceMode: 1355 prefix = "data." 1356 default: 1357 panic(fmt.Errorf("unknown resource mode %s", rsk.Mode)) 1358 } 1359 if rsk.Index == -1 { 1360 return fmt.Sprintf("%s%s.%s", prefix, rsk.Type, rsk.Name) 1361 } 1362 return fmt.Sprintf("%s%s.%s.%d", prefix, rsk.Type, rsk.Name, rsk.Index) 1363 } 1364 1365 // ParseResourceStateKey accepts a key in the format used by 1366 // ModuleState.Resources and returns a resource name and resource index. In the 1367 // state, a resource has the format "type.name.index" or "type.name". In the 1368 // latter case, the index is returned as -1. 1369 func ParseResourceStateKey(k string) (*ResourceStateKey, error) { 1370 parts := strings.Split(k, ".") 1371 mode := config.ManagedResourceMode 1372 if len(parts) > 0 && parts[0] == "data" { 1373 mode = config.DataResourceMode 1374 // Don't need the constant "data" prefix for parsing 1375 // now that we've figured out the mode. 1376 parts = parts[1:] 1377 } 1378 if len(parts) < 2 || len(parts) > 3 { 1379 return nil, fmt.Errorf("Malformed resource state key: %s", k) 1380 } 1381 rsk := &ResourceStateKey{ 1382 Mode: mode, 1383 Type: parts[0], 1384 Name: parts[1], 1385 Index: -1, 1386 } 1387 if len(parts) == 3 { 1388 index, err := strconv.Atoi(parts[2]) 1389 if err != nil { 1390 return nil, fmt.Errorf("Malformed resource state key index: %s", k) 1391 } 1392 rsk.Index = index 1393 } 1394 return rsk, nil 1395 } 1396 1397 // ResourceState holds the state of a resource that is used so that 1398 // a provider can find and manage an existing resource as well as for 1399 // storing attributes that are used to populate variables of child 1400 // resources. 1401 // 1402 // Attributes has attributes about the created resource that are 1403 // queryable in interpolation: "${type.id.attr}" 1404 // 1405 // Extra is just extra data that a provider can return that we store 1406 // for later, but is not exposed in any way to the user. 1407 // 1408 type ResourceState struct { 1409 // This is filled in and managed by Terraform, and is the resource 1410 // type itself such as "mycloud_instance". If a resource provider sets 1411 // this value, it won't be persisted. 1412 Type string `json:"type"` 1413 1414 // Dependencies are a list of things that this resource relies on 1415 // existing to remain intact. For example: an AWS instance might 1416 // depend on a subnet (which itself might depend on a VPC, and so 1417 // on). 1418 // 1419 // Terraform uses this information to build valid destruction 1420 // orders and to warn the user if they're destroying a resource that 1421 // another resource depends on. 1422 // 1423 // Things can be put into this list that may not be managed by 1424 // Terraform. If Terraform doesn't find a matching ID in the 1425 // overall state, then it assumes it isn't managed and doesn't 1426 // worry about it. 1427 Dependencies []string `json:"depends_on"` 1428 1429 // Primary is the current active instance for this resource. 1430 // It can be replaced but only after a successful creation. 1431 // This is the instances on which providers will act. 1432 Primary *InstanceState `json:"primary"` 1433 1434 // Deposed is used in the mechanics of CreateBeforeDestroy: the existing 1435 // Primary is Deposed to get it out of the way for the replacement Primary to 1436 // be created by Apply. If the replacement Primary creates successfully, the 1437 // Deposed instance is cleaned up. 1438 // 1439 // If there were problems creating the replacement Primary, the Deposed 1440 // instance and the (now tainted) replacement Primary will be swapped so the 1441 // tainted replacement will be cleaned up instead. 1442 // 1443 // An instance will remain in the Deposed list until it is successfully 1444 // destroyed and purged. 1445 Deposed []*InstanceState `json:"deposed"` 1446 1447 // Provider is used when a resource is connected to a provider with an alias. 1448 // If this string is empty, the resource is connected to the default provider, 1449 // e.g. "aws_instance" goes with the "aws" provider. 1450 // If the resource block contained a "provider" key, that value will be set here. 1451 Provider string `json:"provider"` 1452 1453 mu sync.Mutex 1454 } 1455 1456 func (s *ResourceState) Lock() { s.mu.Lock() } 1457 func (s *ResourceState) Unlock() { s.mu.Unlock() } 1458 1459 // Equal tests whether two ResourceStates are equal. 1460 func (s *ResourceState) Equal(other *ResourceState) bool { 1461 s.Lock() 1462 defer s.Unlock() 1463 1464 if s.Type != other.Type { 1465 return false 1466 } 1467 1468 if s.Provider != other.Provider { 1469 return false 1470 } 1471 1472 // Dependencies must be equal 1473 sort.Strings(s.Dependencies) 1474 sort.Strings(other.Dependencies) 1475 if len(s.Dependencies) != len(other.Dependencies) { 1476 return false 1477 } 1478 for i, d := range s.Dependencies { 1479 if other.Dependencies[i] != d { 1480 return false 1481 } 1482 } 1483 1484 // States must be equal 1485 if !s.Primary.Equal(other.Primary) { 1486 return false 1487 } 1488 1489 return true 1490 } 1491 1492 // Taint marks a resource as tainted. 1493 func (s *ResourceState) Taint() { 1494 s.Lock() 1495 defer s.Unlock() 1496 1497 if s.Primary != nil { 1498 s.Primary.Tainted = true 1499 } 1500 } 1501 1502 // Untaint unmarks a resource as tainted. 1503 func (s *ResourceState) Untaint() { 1504 s.Lock() 1505 defer s.Unlock() 1506 1507 if s.Primary != nil { 1508 s.Primary.Tainted = false 1509 } 1510 } 1511 1512 func (s *ResourceState) init() { 1513 s.Lock() 1514 defer s.Unlock() 1515 1516 if s.Primary == nil { 1517 s.Primary = &InstanceState{} 1518 } 1519 s.Primary.init() 1520 1521 if s.Dependencies == nil { 1522 s.Dependencies = []string{} 1523 } 1524 1525 if s.Deposed == nil { 1526 s.Deposed = make([]*InstanceState, 0) 1527 } 1528 } 1529 1530 func (s *ResourceState) deepcopy() *ResourceState { 1531 copy, err := copystructure.Config{Lock: true}.Copy(s) 1532 if err != nil { 1533 panic(err) 1534 } 1535 1536 return copy.(*ResourceState) 1537 } 1538 1539 // prune is used to remove any instances that are no longer required 1540 func (s *ResourceState) prune() { 1541 s.Lock() 1542 defer s.Unlock() 1543 1544 n := len(s.Deposed) 1545 for i := 0; i < n; i++ { 1546 inst := s.Deposed[i] 1547 if inst == nil || inst.ID == "" { 1548 copy(s.Deposed[i:], s.Deposed[i+1:]) 1549 s.Deposed[n-1] = nil 1550 n-- 1551 i-- 1552 } 1553 } 1554 s.Deposed = s.Deposed[:n] 1555 1556 s.Dependencies = uniqueStrings(s.Dependencies) 1557 } 1558 1559 func (s *ResourceState) sort() { 1560 s.Lock() 1561 defer s.Unlock() 1562 1563 sort.Strings(s.Dependencies) 1564 } 1565 1566 func (s *ResourceState) String() string { 1567 s.Lock() 1568 defer s.Unlock() 1569 1570 var buf bytes.Buffer 1571 buf.WriteString(fmt.Sprintf("Type = %s", s.Type)) 1572 return buf.String() 1573 } 1574 1575 // InstanceState is used to track the unique state information belonging 1576 // to a given instance. 1577 type InstanceState struct { 1578 // A unique ID for this resource. This is opaque to Terraform 1579 // and is only meant as a lookup mechanism for the providers. 1580 ID string `json:"id"` 1581 1582 // Attributes are basic information about the resource. Any keys here 1583 // are accessible in variable format within Terraform configurations: 1584 // ${resourcetype.name.attribute}. 1585 Attributes map[string]string `json:"attributes"` 1586 1587 // Ephemeral is used to store any state associated with this instance 1588 // that is necessary for the Terraform run to complete, but is not 1589 // persisted to a state file. 1590 Ephemeral EphemeralState `json:"-"` 1591 1592 // Meta is a simple K/V map that is persisted to the State but otherwise 1593 // ignored by Terraform core. It's meant to be used for accounting by 1594 // external client code. The value here must only contain Go primitives 1595 // and collections. 1596 Meta map[string]interface{} `json:"meta"` 1597 1598 // Tainted is used to mark a resource for recreation. 1599 Tainted bool `json:"tainted"` 1600 1601 mu sync.Mutex 1602 } 1603 1604 func (s *InstanceState) Lock() { s.mu.Lock() } 1605 func (s *InstanceState) Unlock() { s.mu.Unlock() } 1606 1607 func (s *InstanceState) init() { 1608 s.Lock() 1609 defer s.Unlock() 1610 1611 if s.Attributes == nil { 1612 s.Attributes = make(map[string]string) 1613 } 1614 if s.Meta == nil { 1615 s.Meta = make(map[string]interface{}) 1616 } 1617 s.Ephemeral.init() 1618 } 1619 1620 // Copy all the Fields from another InstanceState 1621 func (s *InstanceState) Set(from *InstanceState) { 1622 s.Lock() 1623 defer s.Unlock() 1624 1625 from.Lock() 1626 defer from.Unlock() 1627 1628 s.ID = from.ID 1629 s.Attributes = from.Attributes 1630 s.Ephemeral = from.Ephemeral 1631 s.Meta = from.Meta 1632 s.Tainted = from.Tainted 1633 } 1634 1635 func (s *InstanceState) DeepCopy() *InstanceState { 1636 copy, err := copystructure.Config{Lock: true}.Copy(s) 1637 if err != nil { 1638 panic(err) 1639 } 1640 1641 return copy.(*InstanceState) 1642 } 1643 1644 func (s *InstanceState) Empty() bool { 1645 if s == nil { 1646 return true 1647 } 1648 s.Lock() 1649 defer s.Unlock() 1650 1651 return s.ID == "" 1652 } 1653 1654 func (s *InstanceState) Equal(other *InstanceState) bool { 1655 // Short circuit some nil checks 1656 if s == nil || other == nil { 1657 return s == other 1658 } 1659 s.Lock() 1660 defer s.Unlock() 1661 1662 // IDs must be equal 1663 if s.ID != other.ID { 1664 return false 1665 } 1666 1667 // Attributes must be equal 1668 if len(s.Attributes) != len(other.Attributes) { 1669 return false 1670 } 1671 for k, v := range s.Attributes { 1672 otherV, ok := other.Attributes[k] 1673 if !ok { 1674 return false 1675 } 1676 1677 if v != otherV { 1678 return false 1679 } 1680 } 1681 1682 // Meta must be equal 1683 if len(s.Meta) != len(other.Meta) { 1684 return false 1685 } 1686 if s.Meta != nil && other.Meta != nil { 1687 // We only do the deep check if both are non-nil. If one is nil 1688 // we treat it as equal since their lengths are both zero (check 1689 // above). 1690 // 1691 // Since this can contain numeric values that may change types during 1692 // serialization, let's compare the serialized values. 1693 sMeta, err := json.Marshal(s.Meta) 1694 if err != nil { 1695 // marshaling primitives shouldn't ever error out 1696 panic(err) 1697 } 1698 otherMeta, err := json.Marshal(other.Meta) 1699 if err != nil { 1700 panic(err) 1701 } 1702 1703 if !bytes.Equal(sMeta, otherMeta) { 1704 return false 1705 } 1706 } 1707 1708 if s.Tainted != other.Tainted { 1709 return false 1710 } 1711 1712 return true 1713 } 1714 1715 // MergeDiff takes a ResourceDiff and merges the attributes into 1716 // this resource state in order to generate a new state. This new 1717 // state can be used to provide updated attribute lookups for 1718 // variable interpolation. 1719 // 1720 // If the diff attribute requires computing the value, and hence 1721 // won't be available until apply, the value is replaced with the 1722 // computeID. 1723 func (s *InstanceState) MergeDiff(d *InstanceDiff) *InstanceState { 1724 result := s.DeepCopy() 1725 if result == nil { 1726 result = new(InstanceState) 1727 } 1728 result.init() 1729 1730 if s != nil { 1731 s.Lock() 1732 defer s.Unlock() 1733 for k, v := range s.Attributes { 1734 result.Attributes[k] = v 1735 } 1736 } 1737 if d != nil { 1738 for k, diff := range d.CopyAttributes() { 1739 if diff.NewRemoved { 1740 delete(result.Attributes, k) 1741 continue 1742 } 1743 if diff.NewComputed { 1744 result.Attributes[k] = config.UnknownVariableValue 1745 continue 1746 } 1747 1748 result.Attributes[k] = diff.New 1749 } 1750 } 1751 1752 return result 1753 } 1754 1755 func (s *InstanceState) String() string { 1756 s.Lock() 1757 defer s.Unlock() 1758 1759 var buf bytes.Buffer 1760 1761 if s == nil || s.ID == "" { 1762 return "<not created>" 1763 } 1764 1765 buf.WriteString(fmt.Sprintf("ID = %s\n", s.ID)) 1766 1767 attributes := s.Attributes 1768 attrKeys := make([]string, 0, len(attributes)) 1769 for ak, _ := range attributes { 1770 if ak == "id" { 1771 continue 1772 } 1773 1774 attrKeys = append(attrKeys, ak) 1775 } 1776 sort.Strings(attrKeys) 1777 1778 for _, ak := range attrKeys { 1779 av := attributes[ak] 1780 buf.WriteString(fmt.Sprintf("%s = %s\n", ak, av)) 1781 } 1782 1783 buf.WriteString(fmt.Sprintf("Tainted = %t\n", s.Tainted)) 1784 1785 return buf.String() 1786 } 1787 1788 // EphemeralState is used for transient state that is only kept in-memory 1789 type EphemeralState struct { 1790 // ConnInfo is used for the providers to export information which is 1791 // used to connect to the resource for provisioning. For example, 1792 // this could contain SSH or WinRM credentials. 1793 ConnInfo map[string]string `json:"-"` 1794 1795 // Type is used to specify the resource type for this instance. This is only 1796 // required for import operations (as documented). If the documentation 1797 // doesn't state that you need to set this, then don't worry about 1798 // setting it. 1799 Type string `json:"-"` 1800 } 1801 1802 func (e *EphemeralState) init() { 1803 if e.ConnInfo == nil { 1804 e.ConnInfo = make(map[string]string) 1805 } 1806 } 1807 1808 func (e *EphemeralState) DeepCopy() *EphemeralState { 1809 copy, err := copystructure.Config{Lock: true}.Copy(e) 1810 if err != nil { 1811 panic(err) 1812 } 1813 1814 return copy.(*EphemeralState) 1815 } 1816 1817 type jsonStateVersionIdentifier struct { 1818 Version int `json:"version"` 1819 } 1820 1821 // Check if this is a V0 format - the magic bytes at the start of the file 1822 // should be "tfstate" if so. We no longer support upgrading this type of 1823 // state but return an error message explaining to a user how they can 1824 // upgrade via the 0.6.x series. 1825 func testForV0State(buf *bufio.Reader) error { 1826 start, err := buf.Peek(len("tfstate")) 1827 if err != nil { 1828 return fmt.Errorf("Failed to check for magic bytes: %v", err) 1829 } 1830 if string(start) == "tfstate" { 1831 return fmt.Errorf("Terraform 0.7 no longer supports upgrading the binary state\n" + 1832 "format which was used prior to Terraform 0.3. Please upgrade\n" + 1833 "this state file using Terraform 0.6.16 prior to using it with\n" + 1834 "Terraform 0.7.") 1835 } 1836 1837 return nil 1838 } 1839 1840 // ErrNoState is returned by ReadState when the io.Reader contains no data 1841 var ErrNoState = errors.New("no state") 1842 1843 // ReadState reads a state structure out of a reader in the format that 1844 // was written by WriteState. 1845 func ReadState(src io.Reader) (*State, error) { 1846 buf := bufio.NewReader(src) 1847 if _, err := buf.Peek(1); err != nil { 1848 // the error is either io.EOF or "invalid argument", and both are from 1849 // an empty state. 1850 return nil, ErrNoState 1851 } 1852 1853 if err := testForV0State(buf); err != nil { 1854 return nil, err 1855 } 1856 1857 // If we are JSON we buffer the whole thing in memory so we can read it twice. 1858 // This is suboptimal, but will work for now. 1859 jsonBytes, err := ioutil.ReadAll(buf) 1860 if err != nil { 1861 return nil, fmt.Errorf("Reading state file failed: %v", err) 1862 } 1863 1864 versionIdentifier := &jsonStateVersionIdentifier{} 1865 if err := json.Unmarshal(jsonBytes, versionIdentifier); err != nil { 1866 return nil, fmt.Errorf("Decoding state file version failed: %v", err) 1867 } 1868 1869 var result *State 1870 switch versionIdentifier.Version { 1871 case 0: 1872 return nil, fmt.Errorf("State version 0 is not supported as JSON.") 1873 case 1: 1874 v1State, err := ReadStateV1(jsonBytes) 1875 if err != nil { 1876 return nil, err 1877 } 1878 1879 v2State, err := upgradeStateV1ToV2(v1State) 1880 if err != nil { 1881 return nil, err 1882 } 1883 1884 v3State, err := upgradeStateV2ToV3(v2State) 1885 if err != nil { 1886 return nil, err 1887 } 1888 1889 // increment the Serial whenever we upgrade state 1890 v3State.Serial++ 1891 result = v3State 1892 case 2: 1893 v2State, err := ReadStateV2(jsonBytes) 1894 if err != nil { 1895 return nil, err 1896 } 1897 v3State, err := upgradeStateV2ToV3(v2State) 1898 if err != nil { 1899 return nil, err 1900 } 1901 1902 v3State.Serial++ 1903 result = v3State 1904 case 3: 1905 v3State, err := ReadStateV3(jsonBytes) 1906 if err != nil { 1907 return nil, err 1908 } 1909 1910 result = v3State 1911 default: 1912 return nil, fmt.Errorf("Terraform %s does not support state version %d, please update.", 1913 tfversion.SemVer.String(), versionIdentifier.Version) 1914 } 1915 1916 // If we reached this place we must have a result set 1917 if result == nil { 1918 panic("resulting state in load not set, assertion failed") 1919 } 1920 1921 // Prune the state when read it. Its possible to write unpruned states or 1922 // for a user to make a state unpruned (nil-ing a module state for example). 1923 result.prune() 1924 1925 // Validate the state file is valid 1926 if err := result.Validate(); err != nil { 1927 return nil, err 1928 } 1929 1930 return result, nil 1931 } 1932 1933 func ReadStateV1(jsonBytes []byte) (*stateV1, error) { 1934 v1State := &stateV1{} 1935 if err := json.Unmarshal(jsonBytes, v1State); err != nil { 1936 return nil, fmt.Errorf("Decoding state file failed: %v", err) 1937 } 1938 1939 if v1State.Version != 1 { 1940 return nil, fmt.Errorf("Decoded state version did not match the decoder selection: "+ 1941 "read %d, expected 1", v1State.Version) 1942 } 1943 1944 return v1State, nil 1945 } 1946 1947 func ReadStateV2(jsonBytes []byte) (*State, error) { 1948 state := &State{} 1949 if err := json.Unmarshal(jsonBytes, state); err != nil { 1950 return nil, fmt.Errorf("Decoding state file failed: %v", err) 1951 } 1952 1953 // Check the version, this to ensure we don't read a future 1954 // version that we don't understand 1955 if state.Version > StateVersion { 1956 return nil, fmt.Errorf("Terraform %s does not support state version %d, please update.", 1957 tfversion.SemVer.String(), state.Version) 1958 } 1959 1960 // Make sure the version is semantic 1961 if state.TFVersion != "" { 1962 if _, err := version.NewVersion(state.TFVersion); err != nil { 1963 return nil, fmt.Errorf( 1964 "State contains invalid version: %s\n\n"+ 1965 "Terraform validates the version format prior to writing it. This\n"+ 1966 "means that this is invalid of the state becoming corrupted through\n"+ 1967 "some external means. Please manually modify the Terraform version\n"+ 1968 "field to be a proper semantic version.", 1969 state.TFVersion) 1970 } 1971 } 1972 1973 // catch any unitialized fields in the state 1974 state.init() 1975 1976 // Sort it 1977 state.sort() 1978 1979 return state, nil 1980 } 1981 1982 func ReadStateV3(jsonBytes []byte) (*State, error) { 1983 state := &State{} 1984 if err := json.Unmarshal(jsonBytes, state); err != nil { 1985 return nil, fmt.Errorf("Decoding state file failed: %v", err) 1986 } 1987 1988 // Check the version, this to ensure we don't read a future 1989 // version that we don't understand 1990 if state.Version > StateVersion { 1991 return nil, fmt.Errorf("Terraform %s does not support state version %d, please update.", 1992 tfversion.SemVer.String(), state.Version) 1993 } 1994 1995 // Make sure the version is semantic 1996 if state.TFVersion != "" { 1997 if _, err := version.NewVersion(state.TFVersion); err != nil { 1998 return nil, fmt.Errorf( 1999 "State contains invalid version: %s\n\n"+ 2000 "Terraform validates the version format prior to writing it. This\n"+ 2001 "means that this is invalid of the state becoming corrupted through\n"+ 2002 "some external means. Please manually modify the Terraform version\n"+ 2003 "field to be a proper semantic version.", 2004 state.TFVersion) 2005 } 2006 } 2007 2008 // catch any unitialized fields in the state 2009 state.init() 2010 2011 // Sort it 2012 state.sort() 2013 2014 // Now we write the state back out to detect any changes in normaliztion. 2015 // If our state is now written out differently, bump the serial number to 2016 // prevent conflicts. 2017 var buf bytes.Buffer 2018 err := WriteState(state, &buf) 2019 if err != nil { 2020 return nil, err 2021 } 2022 2023 if !bytes.Equal(jsonBytes, buf.Bytes()) { 2024 log.Println("[INFO] state modified during read or write. incrementing serial number") 2025 state.Serial++ 2026 } 2027 2028 return state, nil 2029 } 2030 2031 // WriteState writes a state somewhere in a binary format. 2032 func WriteState(d *State, dst io.Writer) error { 2033 // writing a nil state is a noop. 2034 if d == nil { 2035 return nil 2036 } 2037 2038 // make sure we have no uninitialized fields 2039 d.init() 2040 2041 // Make sure it is sorted 2042 d.sort() 2043 2044 // Ensure the version is set 2045 d.Version = StateVersion 2046 2047 // If the TFVersion is set, verify it. We used to just set the version 2048 // here, but this isn't safe since it changes the MD5 sum on some remote 2049 // state storage backends such as Atlas. We now leave it be if needed. 2050 if d.TFVersion != "" { 2051 if _, err := version.NewVersion(d.TFVersion); err != nil { 2052 return fmt.Errorf( 2053 "Error writing state, invalid version: %s\n\n"+ 2054 "The Terraform version when writing the state must be a semantic\n"+ 2055 "version.", 2056 d.TFVersion) 2057 } 2058 } 2059 2060 // Encode the data in a human-friendly way 2061 data, err := json.MarshalIndent(d, "", " ") 2062 if err != nil { 2063 return fmt.Errorf("Failed to encode state: %s", err) 2064 } 2065 2066 // We append a newline to the data because MarshalIndent doesn't 2067 data = append(data, '\n') 2068 2069 // Write the data out to the dst 2070 if _, err := io.Copy(dst, bytes.NewReader(data)); err != nil { 2071 return fmt.Errorf("Failed to write state: %v", err) 2072 } 2073 2074 return nil 2075 } 2076 2077 // resourceNameSort implements the sort.Interface to sort name parts lexically for 2078 // strings and numerically for integer indexes. 2079 type resourceNameSort []string 2080 2081 func (r resourceNameSort) Len() int { return len(r) } 2082 func (r resourceNameSort) Swap(i, j int) { r[i], r[j] = r[j], r[i] } 2083 2084 func (r resourceNameSort) Less(i, j int) bool { 2085 iParts := strings.Split(r[i], ".") 2086 jParts := strings.Split(r[j], ".") 2087 2088 end := len(iParts) 2089 if len(jParts) < end { 2090 end = len(jParts) 2091 } 2092 2093 for idx := 0; idx < end; idx++ { 2094 if iParts[idx] == jParts[idx] { 2095 continue 2096 } 2097 2098 // sort on the first non-matching part 2099 iInt, iIntErr := strconv.Atoi(iParts[idx]) 2100 jInt, jIntErr := strconv.Atoi(jParts[idx]) 2101 2102 switch { 2103 case iIntErr == nil && jIntErr == nil: 2104 // sort numerically if both parts are integers 2105 return iInt < jInt 2106 case iIntErr == nil: 2107 // numbers sort before strings 2108 return true 2109 case jIntErr == nil: 2110 return false 2111 default: 2112 return iParts[idx] < jParts[idx] 2113 } 2114 } 2115 2116 return r[i] < r[j] 2117 } 2118 2119 // moduleStateSort implements sort.Interface to sort module states 2120 type moduleStateSort []*ModuleState 2121 2122 func (s moduleStateSort) Len() int { 2123 return len(s) 2124 } 2125 2126 func (s moduleStateSort) Less(i, j int) bool { 2127 a := s[i] 2128 b := s[j] 2129 2130 // If either is nil, then the nil one is "less" than 2131 if a == nil || b == nil { 2132 return a == nil 2133 } 2134 2135 // If the lengths are different, then the shorter one always wins 2136 if len(a.Path) != len(b.Path) { 2137 return len(a.Path) < len(b.Path) 2138 } 2139 2140 // Otherwise, compare lexically 2141 return strings.Join(a.Path, ".") < strings.Join(b.Path, ".") 2142 } 2143 2144 func (s moduleStateSort) Swap(i, j int) { 2145 s[i], s[j] = s[j], s[i] 2146 } 2147 2148 const stateValidateErrMultiModule = ` 2149 Multiple modules with the same path: %s 2150 2151 This means that there are multiple entries in the "modules" field 2152 in your state file that point to the same module. This will cause Terraform 2153 to behave in unexpected and error prone ways and is invalid. Please back up 2154 and modify your state file manually to resolve this. 2155 `