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