github.com/jonasi/terraform@v0.6.10-0.20160125170522-e865c342cc1f/terraform/state.go (about) 1 package terraform 2 3 import ( 4 "bufio" 5 "bytes" 6 "encoding/json" 7 "fmt" 8 "io" 9 "log" 10 "reflect" 11 "sort" 12 "strconv" 13 "strings" 14 15 "github.com/hashicorp/terraform/config" 16 ) 17 18 const ( 19 // StateVersion is the current version for our state file 20 StateVersion = 1 21 ) 22 23 // rootModulePath is the path of the root module 24 var rootModulePath = []string{"root"} 25 26 // State keeps track of a snapshot state-of-the-world that Terraform 27 // can use to keep track of what real world resources it is actually 28 // managing. This is the latest format as of Terraform 0.3 29 type State struct { 30 // Version is the protocol version. Currently only "1". 31 Version int `json:"version"` 32 33 // Serial is incremented on any operation that modifies 34 // the State file. It is used to detect potentially conflicting 35 // updates. 36 Serial int64 `json:"serial"` 37 38 // Remote is used to track the metadata required to 39 // pull and push state files from a remote storage endpoint. 40 Remote *RemoteState `json:"remote,omitempty"` 41 42 // Modules contains all the modules in a breadth-first order 43 Modules []*ModuleState `json:"modules"` 44 } 45 46 // NewState is used to initialize a blank state 47 func NewState() *State { 48 s := &State{} 49 s.init() 50 return s 51 } 52 53 // Children returns the ModuleStates that are direct children of 54 // the given path. If the path is "root", for example, then children 55 // returned might be "root.child", but not "root.child.grandchild". 56 func (s *State) Children(path []string) []*ModuleState { 57 // TODO: test 58 59 result := make([]*ModuleState, 0) 60 for _, m := range s.Modules { 61 if len(m.Path) != len(path)+1 { 62 continue 63 } 64 if !reflect.DeepEqual(path, m.Path[:len(path)]) { 65 continue 66 } 67 68 result = append(result, m) 69 } 70 71 return result 72 } 73 74 // AddModule adds the module with the given path to the state. 75 // 76 // This should be the preferred method to add module states since it 77 // allows us to optimize lookups later as well as control sorting. 78 func (s *State) AddModule(path []string) *ModuleState { 79 m := &ModuleState{Path: path} 80 m.init() 81 s.Modules = append(s.Modules, m) 82 s.sort() 83 return m 84 } 85 86 // ModuleByPath is used to lookup the module state for the given path. 87 // This should be the preferred lookup mechanism as it allows for future 88 // lookup optimizations. 89 func (s *State) ModuleByPath(path []string) *ModuleState { 90 if s == nil { 91 return nil 92 } 93 for _, mod := range s.Modules { 94 if mod.Path == nil { 95 panic("missing module path") 96 } 97 if reflect.DeepEqual(mod.Path, path) { 98 return mod 99 } 100 } 101 return nil 102 } 103 104 // ModuleOrphans returns all the module orphans in this state by 105 // returning their full paths. These paths can be used with ModuleByPath 106 // to return the actual state. 107 func (s *State) ModuleOrphans(path []string, c *config.Config) [][]string { 108 // direct keeps track of what direct children we have both in our config 109 // and in our state. childrenKeys keeps track of what isn't an orphan. 110 direct := make(map[string]struct{}) 111 childrenKeys := make(map[string]struct{}) 112 if c != nil { 113 for _, m := range c.Modules { 114 childrenKeys[m.Name] = struct{}{} 115 direct[m.Name] = struct{}{} 116 } 117 } 118 119 // Go over the direct children and find any that aren't in our keys. 120 var orphans [][]string 121 for _, m := range s.Children(path) { 122 key := m.Path[len(m.Path)-1] 123 124 // Record that we found this key as a direct child. We use this 125 // later to find orphan nested modules. 126 direct[key] = struct{}{} 127 128 // If we have a direct child still in our config, it is not an orphan 129 if _, ok := childrenKeys[key]; ok { 130 continue 131 } 132 133 orphans = append(orphans, m.Path) 134 } 135 136 // Find the orphans that are nested... 137 for _, m := range s.Modules { 138 // We only want modules that are at least grandchildren 139 if len(m.Path) < len(path)+2 { 140 continue 141 } 142 143 // If it isn't part of our tree, continue 144 if !reflect.DeepEqual(path, m.Path[:len(path)]) { 145 continue 146 } 147 148 // If we have the direct child, then just skip it. 149 key := m.Path[len(path)] 150 if _, ok := direct[key]; ok { 151 continue 152 } 153 154 // Add this orphan 155 orphans = append(orphans, m.Path[:len(path)+1]) 156 } 157 158 return orphans 159 } 160 161 // Empty returns true if the state is empty. 162 func (s *State) Empty() bool { 163 if s == nil { 164 return true 165 } 166 167 return len(s.Modules) == 0 168 } 169 170 // IsRemote returns true if State represents a state that exists and is 171 // remote. 172 func (s *State) IsRemote() bool { 173 if s == nil { 174 return false 175 } 176 if s.Remote == nil { 177 return false 178 } 179 if s.Remote.Type == "" { 180 return false 181 } 182 183 return true 184 } 185 186 // RootModule returns the ModuleState for the root module 187 func (s *State) RootModule() *ModuleState { 188 root := s.ModuleByPath(rootModulePath) 189 if root == nil { 190 panic("missing root module") 191 } 192 return root 193 } 194 195 // Equal tests if one state is equal to another. 196 func (s *State) Equal(other *State) bool { 197 // If one is nil, we do a direct check 198 if s == nil || other == nil { 199 return s == other 200 } 201 202 // If the versions are different, they're certainly not equal 203 if s.Version != other.Version { 204 return false 205 } 206 207 // If any of the modules are not equal, then this state isn't equal 208 if len(s.Modules) != len(other.Modules) { 209 return false 210 } 211 for _, m := range s.Modules { 212 // This isn't very optimal currently but works. 213 otherM := other.ModuleByPath(m.Path) 214 if otherM == nil { 215 return false 216 } 217 218 // If they're not equal, then we're not equal! 219 if !m.Equal(otherM) { 220 return false 221 } 222 } 223 224 return true 225 } 226 227 // DeepCopy performs a deep copy of the state structure and returns 228 // a new structure. 229 func (s *State) DeepCopy() *State { 230 if s == nil { 231 return nil 232 } 233 n := &State{ 234 Version: s.Version, 235 Serial: s.Serial, 236 Modules: make([]*ModuleState, 0, len(s.Modules)), 237 } 238 for _, mod := range s.Modules { 239 n.Modules = append(n.Modules, mod.deepcopy()) 240 } 241 if s.Remote != nil { 242 n.Remote = s.Remote.deepcopy() 243 } 244 return n 245 } 246 247 // IncrementSerialMaybe increments the serial number of this state 248 // if it different from the other state. 249 func (s *State) IncrementSerialMaybe(other *State) { 250 if s == nil { 251 return 252 } 253 if other == nil { 254 return 255 } 256 if s.Serial > other.Serial { 257 return 258 } 259 if !s.Equal(other) { 260 if other.Serial > s.Serial { 261 s.Serial = other.Serial 262 } 263 264 s.Serial++ 265 } 266 } 267 268 func (s *State) init() { 269 if s.Version == 0 { 270 s.Version = StateVersion 271 } 272 if len(s.Modules) == 0 { 273 root := &ModuleState{ 274 Path: rootModulePath, 275 } 276 root.init() 277 s.Modules = []*ModuleState{root} 278 } 279 } 280 281 // prune is used to remove any resources that are no longer required 282 func (s *State) prune() { 283 if s == nil { 284 return 285 } 286 for _, mod := range s.Modules { 287 mod.prune() 288 } 289 if s.Remote != nil && s.Remote.Empty() { 290 s.Remote = nil 291 } 292 } 293 294 // sort sorts the modules 295 func (s *State) sort() { 296 sort.Sort(moduleStateSort(s.Modules)) 297 298 // Allow modules to be sorted 299 for _, m := range s.Modules { 300 m.sort() 301 } 302 } 303 304 func (s *State) GoString() string { 305 return fmt.Sprintf("*%#v", *s) 306 } 307 308 func (s *State) String() string { 309 if s == nil { 310 return "<nil>" 311 } 312 313 var buf bytes.Buffer 314 for _, m := range s.Modules { 315 mStr := m.String() 316 317 // If we're the root module, we just write the output directly. 318 if reflect.DeepEqual(m.Path, rootModulePath) { 319 buf.WriteString(mStr + "\n") 320 continue 321 } 322 323 buf.WriteString(fmt.Sprintf("module.%s:\n", strings.Join(m.Path[1:], "."))) 324 325 s := bufio.NewScanner(strings.NewReader(mStr)) 326 for s.Scan() { 327 text := s.Text() 328 if text != "" { 329 text = " " + text 330 } 331 332 buf.WriteString(fmt.Sprintf("%s\n", text)) 333 } 334 } 335 336 return strings.TrimSpace(buf.String()) 337 } 338 339 // RemoteState is used to track the information about a remote 340 // state store that we push/pull state to. 341 type RemoteState struct { 342 // Type controls the client we use for the remote state 343 Type string `json:"type"` 344 345 // Config is used to store arbitrary configuration that 346 // is type specific 347 Config map[string]string `json:"config"` 348 } 349 350 func (r *RemoteState) deepcopy() *RemoteState { 351 confCopy := make(map[string]string, len(r.Config)) 352 for k, v := range r.Config { 353 confCopy[k] = v 354 } 355 return &RemoteState{ 356 Type: r.Type, 357 Config: confCopy, 358 } 359 } 360 361 func (r *RemoteState) Empty() bool { 362 return r == nil || r.Type == "" 363 } 364 365 func (r *RemoteState) Equals(other *RemoteState) bool { 366 if r.Type != other.Type { 367 return false 368 } 369 if len(r.Config) != len(other.Config) { 370 return false 371 } 372 for k, v := range r.Config { 373 if other.Config[k] != v { 374 return false 375 } 376 } 377 return true 378 } 379 380 func (r *RemoteState) GoString() string { 381 return fmt.Sprintf("*%#v", *r) 382 } 383 384 // ModuleState is used to track all the state relevant to a single 385 // module. Previous to Terraform 0.3, all state belonged to the "root" 386 // module. 387 type ModuleState struct { 388 // Path is the import path from the root module. Modules imports are 389 // always disjoint, so the path represents amodule tree 390 Path []string `json:"path"` 391 392 // Outputs declared by the module and maintained for each module 393 // even though only the root module technically needs to be kept. 394 // This allows operators to inspect values at the boundaries. 395 Outputs map[string]string `json:"outputs"` 396 397 // Resources is a mapping of the logically named resource to 398 // the state of the resource. Each resource may actually have 399 // N instances underneath, although a user only needs to think 400 // about the 1:1 case. 401 Resources map[string]*ResourceState `json:"resources"` 402 403 // Dependencies are a list of things that this module relies on 404 // existing to remain intact. For example: an module may depend 405 // on a VPC ID given by an aws_vpc resource. 406 // 407 // Terraform uses this information to build valid destruction 408 // orders and to warn the user if they're destroying a module that 409 // another resource depends on. 410 // 411 // Things can be put into this list that may not be managed by 412 // Terraform. If Terraform doesn't find a matching ID in the 413 // overall state, then it assumes it isn't managed and doesn't 414 // worry about it. 415 Dependencies []string `json:"depends_on,omitempty"` 416 } 417 418 // Equal tests whether one module state is equal to another. 419 func (m *ModuleState) Equal(other *ModuleState) bool { 420 // Paths must be equal 421 if !reflect.DeepEqual(m.Path, other.Path) { 422 return false 423 } 424 425 // Outputs must be equal 426 if len(m.Outputs) != len(other.Outputs) { 427 return false 428 } 429 for k, v := range m.Outputs { 430 if other.Outputs[k] != v { 431 return false 432 } 433 } 434 435 // Dependencies must be equal. This sorts these in place but 436 // this shouldn't cause any problems. 437 sort.Strings(m.Dependencies) 438 sort.Strings(other.Dependencies) 439 if len(m.Dependencies) != len(other.Dependencies) { 440 return false 441 } 442 for i, d := range m.Dependencies { 443 if other.Dependencies[i] != d { 444 return false 445 } 446 } 447 448 // Resources must be equal 449 if len(m.Resources) != len(other.Resources) { 450 return false 451 } 452 for k, r := range m.Resources { 453 otherR, ok := other.Resources[k] 454 if !ok { 455 return false 456 } 457 458 if !r.Equal(otherR) { 459 return false 460 } 461 } 462 463 return true 464 } 465 466 // IsRoot says whether or not this module diff is for the root module. 467 func (m *ModuleState) IsRoot() bool { 468 return reflect.DeepEqual(m.Path, rootModulePath) 469 } 470 471 // Orphans returns a list of keys of resources that are in the State 472 // but aren't present in the configuration itself. Hence, these keys 473 // represent the state of resources that are orphans. 474 func (m *ModuleState) Orphans(c *config.Config) []string { 475 keys := make(map[string]struct{}) 476 for k, _ := range m.Resources { 477 keys[k] = struct{}{} 478 } 479 480 if c != nil { 481 for _, r := range c.Resources { 482 delete(keys, r.Id()) 483 484 for k, _ := range keys { 485 if strings.HasPrefix(k, r.Id()+".") { 486 delete(keys, k) 487 } 488 } 489 } 490 } 491 492 result := make([]string, 0, len(keys)) 493 for k, _ := range keys { 494 result = append(result, k) 495 } 496 497 return result 498 } 499 500 // View returns a view with the given resource prefix. 501 func (m *ModuleState) View(id string) *ModuleState { 502 if m == nil { 503 return m 504 } 505 506 r := m.deepcopy() 507 for k, _ := range r.Resources { 508 if id == k || strings.HasPrefix(k, id+".") { 509 continue 510 } 511 512 delete(r.Resources, k) 513 } 514 515 return r 516 } 517 518 func (m *ModuleState) init() { 519 if m.Outputs == nil { 520 m.Outputs = make(map[string]string) 521 } 522 if m.Resources == nil { 523 m.Resources = make(map[string]*ResourceState) 524 } 525 } 526 527 func (m *ModuleState) deepcopy() *ModuleState { 528 if m == nil { 529 return nil 530 } 531 n := &ModuleState{ 532 Path: make([]string, len(m.Path)), 533 Outputs: make(map[string]string, len(m.Outputs)), 534 Resources: make(map[string]*ResourceState, len(m.Resources)), 535 } 536 copy(n.Path, m.Path) 537 for k, v := range m.Outputs { 538 n.Outputs[k] = v 539 } 540 for k, v := range m.Resources { 541 n.Resources[k] = v.deepcopy() 542 } 543 return n 544 } 545 546 // prune is used to remove any resources that are no longer required 547 func (m *ModuleState) prune() { 548 for k, v := range m.Resources { 549 v.prune() 550 551 if (v.Primary == nil || v.Primary.ID == "") && len(v.Tainted) == 0 && len(v.Deposed) == 0 { 552 delete(m.Resources, k) 553 } 554 } 555 556 for k, v := range m.Outputs { 557 if v == config.UnknownVariableValue { 558 delete(m.Outputs, k) 559 } 560 } 561 } 562 563 func (m *ModuleState) sort() { 564 for _, v := range m.Resources { 565 v.sort() 566 } 567 } 568 569 func (m *ModuleState) GoString() string { 570 return fmt.Sprintf("*%#v", *m) 571 } 572 573 func (m *ModuleState) String() string { 574 var buf bytes.Buffer 575 576 if len(m.Resources) == 0 { 577 buf.WriteString("<no state>") 578 } 579 580 names := make([]string, 0, len(m.Resources)) 581 for name, _ := range m.Resources { 582 names = append(names, name) 583 } 584 sort.Strings(names) 585 586 for _, k := range names { 587 rs := m.Resources[k] 588 var id string 589 if rs.Primary != nil { 590 id = rs.Primary.ID 591 } 592 if id == "" { 593 id = "<not created>" 594 } 595 596 taintStr := "" 597 if len(rs.Tainted) > 0 { 598 taintStr = fmt.Sprintf(" (%d tainted)", len(rs.Tainted)) 599 } 600 601 deposedStr := "" 602 if len(rs.Deposed) > 0 { 603 deposedStr = fmt.Sprintf(" (%d deposed)", len(rs.Deposed)) 604 } 605 606 buf.WriteString(fmt.Sprintf("%s:%s%s\n", k, taintStr, deposedStr)) 607 buf.WriteString(fmt.Sprintf(" ID = %s\n", id)) 608 if rs.Provider != "" { 609 buf.WriteString(fmt.Sprintf(" provider = %s\n", rs.Provider)) 610 } 611 612 var attributes map[string]string 613 if rs.Primary != nil { 614 attributes = rs.Primary.Attributes 615 } 616 attrKeys := make([]string, 0, len(attributes)) 617 for ak, _ := range attributes { 618 if ak == "id" { 619 continue 620 } 621 622 attrKeys = append(attrKeys, ak) 623 } 624 sort.Strings(attrKeys) 625 626 for _, ak := range attrKeys { 627 av := attributes[ak] 628 buf.WriteString(fmt.Sprintf(" %s = %s\n", ak, av)) 629 } 630 631 for idx, t := range rs.Tainted { 632 buf.WriteString(fmt.Sprintf(" Tainted ID %d = %s\n", idx+1, t.ID)) 633 } 634 635 for idx, t := range rs.Deposed { 636 buf.WriteString(fmt.Sprintf(" Deposed ID %d = %s\n", idx+1, t.ID)) 637 } 638 639 if len(rs.Dependencies) > 0 { 640 buf.WriteString(fmt.Sprintf("\n Dependencies:\n")) 641 for _, dep := range rs.Dependencies { 642 buf.WriteString(fmt.Sprintf(" %s\n", dep)) 643 } 644 } 645 } 646 647 if len(m.Outputs) > 0 { 648 buf.WriteString("\nOutputs:\n\n") 649 650 ks := make([]string, 0, len(m.Outputs)) 651 for k, _ := range m.Outputs { 652 ks = append(ks, k) 653 } 654 sort.Strings(ks) 655 656 for _, k := range ks { 657 v := m.Outputs[k] 658 buf.WriteString(fmt.Sprintf("%s = %s\n", k, v)) 659 } 660 } 661 662 return buf.String() 663 } 664 665 // ResourceStateKey is a structured representation of the key used for the 666 // ModuleState.Resources mapping 667 type ResourceStateKey struct { 668 Name string 669 Type string 670 Index int 671 } 672 673 // Equal determines whether two ResourceStateKeys are the same 674 func (rsk *ResourceStateKey) Equal(other *ResourceStateKey) bool { 675 if rsk == nil || other == nil { 676 return false 677 } 678 if rsk.Type != other.Type { 679 return false 680 } 681 if rsk.Name != other.Name { 682 return false 683 } 684 if rsk.Index != other.Index { 685 return false 686 } 687 return true 688 } 689 690 func (rsk *ResourceStateKey) String() string { 691 if rsk == nil { 692 return "" 693 } 694 if rsk.Index == -1 { 695 return fmt.Sprintf("%s.%s", rsk.Type, rsk.Name) 696 } 697 return fmt.Sprintf("%s.%s.%d", rsk.Type, rsk.Name, rsk.Index) 698 } 699 700 // ParseResourceStateKey accepts a key in the format used by 701 // ModuleState.Resources and returns a resource name and resource index. In the 702 // state, a resource has the format "type.name.index" or "type.name". In the 703 // latter case, the index is returned as -1. 704 func ParseResourceStateKey(k string) (*ResourceStateKey, error) { 705 parts := strings.Split(k, ".") 706 if len(parts) < 2 || len(parts) > 3 { 707 return nil, fmt.Errorf("Malformed resource state key: %s", k) 708 } 709 rsk := &ResourceStateKey{ 710 Type: parts[0], 711 Name: parts[1], 712 Index: -1, 713 } 714 if len(parts) == 3 { 715 index, err := strconv.Atoi(parts[2]) 716 if err != nil { 717 return nil, fmt.Errorf("Malformed resource state key index: %s", k) 718 } 719 rsk.Index = index 720 } 721 return rsk, nil 722 } 723 724 // ResourceState holds the state of a resource that is used so that 725 // a provider can find and manage an existing resource as well as for 726 // storing attributes that are used to populate variables of child 727 // resources. 728 // 729 // Attributes has attributes about the created resource that are 730 // queryable in interpolation: "${type.id.attr}" 731 // 732 // Extra is just extra data that a provider can return that we store 733 // for later, but is not exposed in any way to the user. 734 // 735 type ResourceState struct { 736 // This is filled in and managed by Terraform, and is the resource 737 // type itself such as "mycloud_instance". If a resource provider sets 738 // this value, it won't be persisted. 739 Type string `json:"type"` 740 741 // Dependencies are a list of things that this resource relies on 742 // existing to remain intact. For example: an AWS instance might 743 // depend on a subnet (which itself might depend on a VPC, and so 744 // on). 745 // 746 // Terraform uses this information to build valid destruction 747 // orders and to warn the user if they're destroying a resource that 748 // another resource depends on. 749 // 750 // Things can be put into this list that may not be managed by 751 // Terraform. If Terraform doesn't find a matching ID in the 752 // overall state, then it assumes it isn't managed and doesn't 753 // worry about it. 754 Dependencies []string `json:"depends_on,omitempty"` 755 756 // Primary is the current active instance for this resource. 757 // It can be replaced but only after a successful creation. 758 // This is the instances on which providers will act. 759 Primary *InstanceState `json:"primary"` 760 761 // Tainted is used to track any underlying instances that 762 // have been created but are in a bad or unknown state and 763 // need to be cleaned up subsequently. In the 764 // standard case, there is only at most a single instance. 765 // However, in pathological cases, it is possible for the number 766 // of instances to accumulate. 767 Tainted []*InstanceState `json:"tainted,omitempty"` 768 769 // Deposed is used in the mechanics of CreateBeforeDestroy: the existing 770 // Primary is Deposed to get it out of the way for the replacement Primary to 771 // be created by Apply. If the replacement Primary creates successfully, the 772 // Deposed instance is cleaned up. If there were problems creating the 773 // replacement, the instance remains in the Deposed list so it can be 774 // destroyed in a future run. Functionally, Deposed instances are very 775 // similar to Tainted instances in that Terraform is only tracking them in 776 // order to remember to destroy them. 777 Deposed []*InstanceState `json:"deposed,omitempty"` 778 779 // Provider is used when a resource is connected to a provider with an alias. 780 // If this string is empty, the resource is connected to the default provider, 781 // e.g. "aws_instance" goes with the "aws" provider. 782 // If the resource block contained a "provider" key, that value will be set here. 783 Provider string `json:"provider,omitempty"` 784 } 785 786 // Equal tests whether two ResourceStates are equal. 787 func (s *ResourceState) Equal(other *ResourceState) bool { 788 if s.Type != other.Type { 789 return false 790 } 791 792 if s.Provider != other.Provider { 793 return false 794 } 795 796 // Dependencies must be equal 797 sort.Strings(s.Dependencies) 798 sort.Strings(other.Dependencies) 799 if len(s.Dependencies) != len(other.Dependencies) { 800 return false 801 } 802 for i, d := range s.Dependencies { 803 if other.Dependencies[i] != d { 804 return false 805 } 806 } 807 808 // States must be equal 809 if !s.Primary.Equal(other.Primary) { 810 return false 811 } 812 813 // Tainted 814 taints := make(map[string]*InstanceState) 815 for _, t := range other.Tainted { 816 if t == nil { 817 continue 818 } 819 820 taints[t.ID] = t 821 } 822 for _, t := range s.Tainted { 823 if t == nil { 824 continue 825 } 826 827 otherT, ok := taints[t.ID] 828 if !ok { 829 return false 830 } 831 delete(taints, t.ID) 832 833 if !t.Equal(otherT) { 834 return false 835 } 836 } 837 838 // This means that we have stuff in other tainted that we don't 839 // have, so it is not equal. 840 if len(taints) > 0 { 841 return false 842 } 843 844 return true 845 } 846 847 // Taint takes the primary state and marks it as tainted. If there is no 848 // primary state, this does nothing. 849 func (r *ResourceState) Taint() { 850 // If there is no primary, nothing to do 851 if r.Primary == nil { 852 return 853 } 854 855 // Shuffle to the end of the taint list and set primary to nil 856 r.Tainted = append(r.Tainted, r.Primary) 857 r.Primary = nil 858 } 859 860 func (r *ResourceState) init() { 861 if r.Primary == nil { 862 r.Primary = &InstanceState{} 863 } 864 r.Primary.init() 865 } 866 867 func (r *ResourceState) deepcopy() *ResourceState { 868 if r == nil { 869 return nil 870 } 871 872 n := &ResourceState{ 873 Type: r.Type, 874 Dependencies: nil, 875 Primary: r.Primary.deepcopy(), 876 Tainted: nil, 877 Provider: r.Provider, 878 } 879 if r.Dependencies != nil { 880 n.Dependencies = make([]string, len(r.Dependencies)) 881 copy(n.Dependencies, r.Dependencies) 882 } 883 if r.Tainted != nil { 884 n.Tainted = make([]*InstanceState, 0, len(r.Tainted)) 885 for _, inst := range r.Tainted { 886 n.Tainted = append(n.Tainted, inst.deepcopy()) 887 } 888 } 889 if r.Deposed != nil { 890 n.Deposed = make([]*InstanceState, 0, len(r.Deposed)) 891 for _, inst := range r.Deposed { 892 n.Deposed = append(n.Deposed, inst.deepcopy()) 893 } 894 } 895 896 return n 897 } 898 899 // prune is used to remove any instances that are no longer required 900 func (r *ResourceState) prune() { 901 n := len(r.Tainted) 902 for i := 0; i < n; i++ { 903 inst := r.Tainted[i] 904 if inst == nil || inst.ID == "" { 905 copy(r.Tainted[i:], r.Tainted[i+1:]) 906 r.Tainted[n-1] = nil 907 n-- 908 i-- 909 } 910 } 911 912 r.Tainted = r.Tainted[:n] 913 914 n = len(r.Deposed) 915 for i := 0; i < n; i++ { 916 inst := r.Deposed[i] 917 if inst == nil || inst.ID == "" { 918 copy(r.Deposed[i:], r.Deposed[i+1:]) 919 r.Deposed[n-1] = nil 920 n-- 921 i-- 922 } 923 } 924 925 r.Deposed = r.Deposed[:n] 926 } 927 928 func (r *ResourceState) sort() { 929 sort.Strings(r.Dependencies) 930 } 931 932 func (s *ResourceState) GoString() string { 933 return fmt.Sprintf("*%#v", *s) 934 } 935 936 func (s *ResourceState) String() string { 937 var buf bytes.Buffer 938 buf.WriteString(fmt.Sprintf("Type = %s", s.Type)) 939 return buf.String() 940 } 941 942 // InstanceState is used to track the unique state information belonging 943 // to a given instance. 944 type InstanceState struct { 945 // A unique ID for this resource. This is opaque to Terraform 946 // and is only meant as a lookup mechanism for the providers. 947 ID string `json:"id"` 948 949 // Attributes are basic information about the resource. Any keys here 950 // are accessible in variable format within Terraform configurations: 951 // ${resourcetype.name.attribute}. 952 Attributes map[string]string `json:"attributes,omitempty"` 953 954 // Ephemeral is used to store any state associated with this instance 955 // that is necessary for the Terraform run to complete, but is not 956 // persisted to a state file. 957 Ephemeral EphemeralState `json:"-"` 958 959 // Meta is a simple K/V map that is persisted to the State but otherwise 960 // ignored by Terraform core. It's meant to be used for accounting by 961 // external client code. 962 Meta map[string]string `json:"meta,omitempty"` 963 } 964 965 func (i *InstanceState) init() { 966 if i.Attributes == nil { 967 i.Attributes = make(map[string]string) 968 } 969 if i.Meta == nil { 970 i.Meta = make(map[string]string) 971 } 972 i.Ephemeral.init() 973 } 974 975 func (i *InstanceState) deepcopy() *InstanceState { 976 if i == nil { 977 return nil 978 } 979 n := &InstanceState{ 980 ID: i.ID, 981 Ephemeral: *i.Ephemeral.deepcopy(), 982 } 983 if i.Attributes != nil { 984 n.Attributes = make(map[string]string, len(i.Attributes)) 985 for k, v := range i.Attributes { 986 n.Attributes[k] = v 987 } 988 } 989 if i.Meta != nil { 990 n.Meta = make(map[string]string, len(i.Meta)) 991 for k, v := range i.Meta { 992 n.Meta[k] = v 993 } 994 } 995 return n 996 } 997 998 func (s *InstanceState) Empty() bool { 999 return s == nil || s.ID == "" 1000 } 1001 1002 func (s *InstanceState) Equal(other *InstanceState) bool { 1003 // Short circuit some nil checks 1004 if s == nil || other == nil { 1005 return s == other 1006 } 1007 1008 // IDs must be equal 1009 if s.ID != other.ID { 1010 return false 1011 } 1012 1013 // Attributes must be equal 1014 if len(s.Attributes) != len(other.Attributes) { 1015 return false 1016 } 1017 for k, v := range s.Attributes { 1018 otherV, ok := other.Attributes[k] 1019 if !ok { 1020 return false 1021 } 1022 1023 if v != otherV { 1024 return false 1025 } 1026 } 1027 1028 // Meta must be equal 1029 if len(s.Meta) != len(other.Meta) { 1030 return false 1031 } 1032 for k, v := range s.Meta { 1033 otherV, ok := other.Meta[k] 1034 if !ok { 1035 return false 1036 } 1037 1038 if v != otherV { 1039 return false 1040 } 1041 } 1042 1043 return true 1044 } 1045 1046 // MergeDiff takes a ResourceDiff and merges the attributes into 1047 // this resource state in order to generate a new state. This new 1048 // state can be used to provide updated attribute lookups for 1049 // variable interpolation. 1050 // 1051 // If the diff attribute requires computing the value, and hence 1052 // won't be available until apply, the value is replaced with the 1053 // computeID. 1054 func (s *InstanceState) MergeDiff(d *InstanceDiff) *InstanceState { 1055 result := s.deepcopy() 1056 if result == nil { 1057 result = new(InstanceState) 1058 } 1059 result.init() 1060 1061 if s != nil { 1062 for k, v := range s.Attributes { 1063 result.Attributes[k] = v 1064 } 1065 } 1066 if d != nil { 1067 for k, diff := range d.Attributes { 1068 if diff.NewRemoved { 1069 delete(result.Attributes, k) 1070 continue 1071 } 1072 if diff.NewComputed { 1073 result.Attributes[k] = config.UnknownVariableValue 1074 continue 1075 } 1076 1077 result.Attributes[k] = diff.New 1078 } 1079 } 1080 1081 return result 1082 } 1083 1084 func (i *InstanceState) GoString() string { 1085 return fmt.Sprintf("*%#v", *i) 1086 } 1087 1088 func (i *InstanceState) String() string { 1089 var buf bytes.Buffer 1090 1091 if i == nil || i.ID == "" { 1092 return "<not created>" 1093 } 1094 1095 buf.WriteString(fmt.Sprintf("ID = %s\n", i.ID)) 1096 1097 attributes := i.Attributes 1098 attrKeys := make([]string, 0, len(attributes)) 1099 for ak, _ := range attributes { 1100 if ak == "id" { 1101 continue 1102 } 1103 1104 attrKeys = append(attrKeys, ak) 1105 } 1106 sort.Strings(attrKeys) 1107 1108 for _, ak := range attrKeys { 1109 av := attributes[ak] 1110 buf.WriteString(fmt.Sprintf("%s = %s\n", ak, av)) 1111 } 1112 1113 return buf.String() 1114 } 1115 1116 // EphemeralState is used for transient state that is only kept in-memory 1117 type EphemeralState struct { 1118 // ConnInfo is used for the providers to export information which is 1119 // used to connect to the resource for provisioning. For example, 1120 // this could contain SSH or WinRM credentials. 1121 ConnInfo map[string]string `json:"-"` 1122 } 1123 1124 func (e *EphemeralState) init() { 1125 if e.ConnInfo == nil { 1126 e.ConnInfo = make(map[string]string) 1127 } 1128 } 1129 1130 func (e *EphemeralState) deepcopy() *EphemeralState { 1131 if e == nil { 1132 return nil 1133 } 1134 n := &EphemeralState{} 1135 if e.ConnInfo != nil { 1136 n.ConnInfo = make(map[string]string, len(e.ConnInfo)) 1137 for k, v := range e.ConnInfo { 1138 n.ConnInfo[k] = v 1139 } 1140 } 1141 return n 1142 } 1143 1144 // ReadState reads a state structure out of a reader in the format that 1145 // was written by WriteState. 1146 func ReadState(src io.Reader) (*State, error) { 1147 buf := bufio.NewReader(src) 1148 1149 // Check if this is a V1 format 1150 start, err := buf.Peek(len(stateFormatMagic)) 1151 if err != nil { 1152 return nil, fmt.Errorf("Failed to check for magic bytes: %v", err) 1153 } 1154 if string(start) == stateFormatMagic { 1155 // Read the old state 1156 old, err := ReadStateV1(buf) 1157 if err != nil { 1158 return nil, err 1159 } 1160 return upgradeV1State(old) 1161 } 1162 1163 // Otherwise, must be V2 1164 dec := json.NewDecoder(buf) 1165 state := &State{} 1166 if err := dec.Decode(state); err != nil { 1167 return nil, fmt.Errorf("Decoding state file failed: %v", err) 1168 } 1169 1170 // Check the version, this to ensure we don't read a future 1171 // version that we don't understand 1172 if state.Version > StateVersion { 1173 return nil, fmt.Errorf("State version %d not supported, please update.", 1174 state.Version) 1175 } 1176 1177 // Sort it 1178 state.sort() 1179 1180 return state, nil 1181 } 1182 1183 // WriteState writes a state somewhere in a binary format. 1184 func WriteState(d *State, dst io.Writer) error { 1185 // Make sure it is sorted 1186 d.sort() 1187 1188 // Ensure the version is set 1189 d.Version = StateVersion 1190 1191 // Encode the data in a human-friendly way 1192 data, err := json.MarshalIndent(d, "", " ") 1193 if err != nil { 1194 return fmt.Errorf("Failed to encode state: %s", err) 1195 } 1196 1197 // We append a newline to the data because MarshalIndent doesn't 1198 data = append(data, '\n') 1199 1200 // Write the data out to the dst 1201 if _, err := io.Copy(dst, bytes.NewReader(data)); err != nil { 1202 return fmt.Errorf("Failed to write state: %v", err) 1203 } 1204 1205 return nil 1206 } 1207 1208 // upgradeV1State is used to upgrade a V1 state representation 1209 // into a proper State representation. 1210 func upgradeV1State(old *StateV1) (*State, error) { 1211 s := &State{} 1212 s.init() 1213 1214 // Old format had no modules, so we migrate everything 1215 // directly into the root module. 1216 root := s.RootModule() 1217 1218 // Copy the outputs 1219 root.Outputs = old.Outputs 1220 1221 // Upgrade the resources 1222 for id, rs := range old.Resources { 1223 newRs := &ResourceState{ 1224 Type: rs.Type, 1225 } 1226 root.Resources[id] = newRs 1227 1228 // Migrate to an instance state 1229 instance := &InstanceState{ 1230 ID: rs.ID, 1231 Attributes: rs.Attributes, 1232 } 1233 1234 // Check if this is the primary or tainted instance 1235 if _, ok := old.Tainted[id]; ok { 1236 newRs.Tainted = append(newRs.Tainted, instance) 1237 } else { 1238 newRs.Primary = instance 1239 } 1240 1241 // Warn if the resource uses Extra, as there is 1242 // no upgrade path for this! Now totally deprecated. 1243 if len(rs.Extra) > 0 { 1244 log.Printf( 1245 "[WARN] Resource %s uses deprecated attribute "+ 1246 "storage, state file upgrade may be incomplete.", 1247 rs.ID, 1248 ) 1249 } 1250 } 1251 return s, nil 1252 } 1253 1254 // moduleStateSort implements sort.Interface to sort module states 1255 type moduleStateSort []*ModuleState 1256 1257 func (s moduleStateSort) Len() int { 1258 return len(s) 1259 } 1260 1261 func (s moduleStateSort) Less(i, j int) bool { 1262 a := s[i] 1263 b := s[j] 1264 1265 // If the lengths are different, then the shorter one always wins 1266 if len(a.Path) != len(b.Path) { 1267 return len(a.Path) < len(b.Path) 1268 } 1269 1270 // Otherwise, compare lexically 1271 return strings.Join(a.Path, ".") < strings.Join(b.Path, ".") 1272 } 1273 1274 func (s moduleStateSort) Swap(i, j int) { 1275 s[i], s[j] = s[j], s[i] 1276 }