github.com/nicgrayson/terraform@v0.4.3-0.20150415203910-c4de50829380/command/refresh.go (about) 1 package command 2 3 import ( 4 "fmt" 5 "log" 6 "os" 7 "strings" 8 ) 9 10 // RefreshCommand is a cli.Command implementation that refreshes the state 11 // file. 12 type RefreshCommand struct { 13 Meta 14 } 15 16 func (c *RefreshCommand) Run(args []string) int { 17 args = c.Meta.process(args, true) 18 19 cmdFlags := c.Meta.flagSet("refresh") 20 cmdFlags.StringVar(&c.Meta.statePath, "state", DefaultStateFilename, "path") 21 cmdFlags.StringVar(&c.Meta.stateOutPath, "state-out", "", "path") 22 cmdFlags.StringVar(&c.Meta.backupPath, "backup", "", "path") 23 cmdFlags.Usage = func() { c.Ui.Error(c.Help()) } 24 if err := cmdFlags.Parse(args); err != nil { 25 return 1 26 } 27 28 var configPath string 29 args = cmdFlags.Args() 30 if len(args) > 1 { 31 c.Ui.Error("The refresh command expects at most one argument.") 32 cmdFlags.Usage() 33 return 1 34 } else if len(args) == 1 { 35 configPath = args[0] 36 } else { 37 var err error 38 configPath, err = os.Getwd() 39 if err != nil { 40 c.Ui.Error(fmt.Sprintf("Error getting pwd: %s", err)) 41 } 42 } 43 44 // Check if remote state is enabled 45 state, err := c.State() 46 if err != nil { 47 c.Ui.Error(fmt.Sprintf("Failed to load state: %s", err)) 48 return 1 49 } 50 51 // Verify that the state path exists. The "ContextArg" function below 52 // will actually do this, but we want to provide a richer error message 53 // if possible. 54 if !state.State().IsRemote() { 55 if _, err := os.Stat(c.Meta.statePath); err != nil { 56 if os.IsNotExist(err) { 57 c.Ui.Error(fmt.Sprintf( 58 "The Terraform state file for your infrastructure does not\n"+ 59 "exist. The 'refresh' command only works and only makes sense\n"+ 60 "when there is existing state that Terraform is managing. Please\n"+ 61 "double-check the value given below and try again. If you\n"+ 62 "haven't created infrastructure with Terraform yet, use the\n"+ 63 "'terraform apply' command.\n\n"+ 64 "Path: %s", 65 c.Meta.statePath)) 66 return 1 67 } 68 69 c.Ui.Error(fmt.Sprintf( 70 "There was an error reading the Terraform state that is needed\n"+ 71 "for refreshing. The path and error are shown below.\n\n"+ 72 "Path: %s\n\nError: %s", 73 c.Meta.statePath, 74 err)) 75 return 1 76 } 77 } 78 79 // Build the context based on the arguments given 80 ctx, _, err := c.Context(contextOpts{ 81 Path: configPath, 82 StatePath: c.Meta.statePath, 83 }) 84 if err != nil { 85 c.Ui.Error(err.Error()) 86 return 1 87 } 88 if !validateContext(ctx, c.Ui) { 89 return 1 90 } 91 if err := ctx.Input(c.InputMode()); err != nil { 92 c.Ui.Error(fmt.Sprintf("Error configuring: %s", err)) 93 return 1 94 } 95 96 newState, err := ctx.Refresh() 97 if err != nil { 98 c.Ui.Error(fmt.Sprintf("Error refreshing state: %s", err)) 99 return 1 100 } 101 102 log.Printf("[INFO] Writing state output to: %s", c.Meta.StateOutPath()) 103 if err := c.Meta.PersistState(newState); err != nil { 104 c.Ui.Error(fmt.Sprintf("Error writing state file: %s", err)) 105 return 1 106 } 107 108 return 0 109 } 110 111 func (c *RefreshCommand) Help() string { 112 helpText := ` 113 Usage: terraform refresh [options] [dir] 114 115 Update the state file of your infrastructure with metadata that matches 116 the physical resources they are tracking. 117 118 This will not modify your infrastructure, but it can modify your 119 state file to update metadata. This metadata might cause new changes 120 to occur when you generate a plan or call apply next. 121 122 Options: 123 124 -backup=path Path to backup the existing state file before 125 modifying. Defaults to the "-state-out" path with 126 ".backup" extension. Set to "-" to disable backup. 127 128 -input=true Ask for input for variables if not directly set. 129 130 -no-color If specified, output won't contain any color. 131 132 -state=path Path to read and save state (unless state-out 133 is specified). Defaults to "terraform.tfstate". 134 135 -state-out=path Path to write updated state file. By default, the 136 "-state" path will be used. 137 138 -target=resource Resource to target. Operation will be limited to this 139 resource and its dependencies. This flag can be used 140 multiple times. 141 142 -var 'foo=bar' Set a variable in the Terraform configuration. This 143 flag can be set multiple times. 144 145 -var-file=foo Set variables in the Terraform configuration from 146 a file. If "terraform.tfvars" is present, it will be 147 automatically loaded if this flag is not specified. 148 149 ` 150 return strings.TrimSpace(helpText) 151 } 152 153 func (c *RefreshCommand) Synopsis() string { 154 return "Update local state file against real resources" 155 }