github.com/ibm-cloud/terraform@v0.6.4-0.20170726051544-8872b87621df/command/state_meta.go (about) 1 package command 2 3 import ( 4 "errors" 5 "fmt" 6 "time" 7 8 backendlocal "github.com/hashicorp/terraform/backend/local" 9 "github.com/hashicorp/terraform/state" 10 "github.com/hashicorp/terraform/terraform" 11 ) 12 13 // StateMeta is the meta struct that should be embedded in state subcommands. 14 type StateMeta struct{} 15 16 // State returns the state for this meta. This gets the appropriate state from 17 // the backend, but changes the way that backups are done. This configures 18 // backups to be timestamped rather than just the original state path plus a 19 // backup path. 20 func (c *StateMeta) State(m *Meta) (state.State, error) { 21 // Load the backend 22 b, err := m.Backend(nil) 23 if err != nil { 24 return nil, err 25 } 26 27 env := m.Env() 28 // Get the state 29 s, err := b.State(env) 30 if err != nil { 31 return nil, err 32 } 33 34 // Get a local backend 35 localRaw, err := m.Backend(&BackendOpts{ForceLocal: true}) 36 if err != nil { 37 // This should never fail 38 panic(err) 39 } 40 localB := localRaw.(*backendlocal.Local) 41 _, stateOutPath, _ := localB.StatePaths(env) 42 if err != nil { 43 return nil, err 44 } 45 46 // Determine the backup path. stateOutPath is set to the resulting 47 // file where state is written (cached in the case of remote state) 48 backupPath := fmt.Sprintf( 49 "%s.%d%s", 50 stateOutPath, 51 time.Now().UTC().Unix(), 52 DefaultBackupExtension) 53 54 // Wrap it for backups 55 s = &state.BackupState{ 56 Real: s, 57 Path: backupPath, 58 } 59 60 return s, nil 61 } 62 63 // filterInstance filters a single instance out of filter results. 64 func (c *StateMeta) filterInstance(rs []*terraform.StateFilterResult) (*terraform.StateFilterResult, error) { 65 var result *terraform.StateFilterResult 66 for _, r := range rs { 67 if _, ok := r.Value.(*terraform.InstanceState); !ok { 68 continue 69 } 70 71 if result != nil { 72 return nil, errors.New(errStateMultiple) 73 } 74 75 result = r 76 } 77 78 return result, nil 79 } 80 81 const errStateMultiple = `Multiple instances found for the given pattern! 82 83 This command requires that the pattern match exactly one instance 84 of a resource. To view the matched instances, use "terraform state list". 85 Please modify the pattern to match only a single instance.`