Repository navigation
Expand file tree
/
Copy pathrefresh.go
More file actions
137 lines (114 loc) · 3.49 KB
/
Copy pathrefresh.go
File metadata and controls
137 lines (114 loc) · 3.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package command
import (
"flag"
"fmt"
"log"
"os"
"strings"
"github.com/hashicorp/terraform/terraform"
)
// RefreshCommand is a cli.Command implementation that refreshes the state
// file.
type RefreshCommand struct {
Meta
}
func (c *RefreshCommand) Run(args []string) int {
var statePath, stateOutPath string
args = c.Meta.process(args)
cmdFlags := flag.NewFlagSet("refresh", flag.ContinueOnError)
cmdFlags.StringVar(&statePath, "state", DefaultStateFilename, "path")
cmdFlags.StringVar(&stateOutPath, "state-out", "", "path")
cmdFlags.Usage = func() { c.Ui.Error(c.Help()) }
if err := cmdFlags.Parse(args); err != nil {
return 1
}
var configPath string
args = cmdFlags.Args()
if len(args) > 1 {
c.Ui.Error("The apply command expacts at most one argument.")
cmdFlags.Usage()
return 1
} else if len(args) == 1 {
configPath = args[0]
} else {
var err error
configPath, err = os.Getwd()
if err != nil {
c.Ui.Error(fmt.Sprintf("Error getting pwd: %s", err))
}
}
// If we don't specify an output path, default to out normal state
// path.
if stateOutPath == "" {
stateOutPath = statePath
}
// Verify that the state path exists. The "ContextArg" function below
// will actually do this, but we want to provide a richer error message
// if possible.
if _, err := os.Stat(statePath); err != nil {
if os.IsNotExist(err) {
c.Ui.Error(fmt.Sprintf(
"The Terraform state file for your infrastructure does not\n"+
"exist. The 'refresh' command only works and only makes sense\n"+
"when there is existing state that Terraform is managing. Please\n"+
"double-check the value given below and try again. If you\n"+
"haven't created infrastructure with Terraform yet, use the\n"+
"'terraform apply' command.\n\n"+
"Path: %s",
statePath))
return 1
}
c.Ui.Error(fmt.Sprintf(
"There was an error reading the Terraform state that is needed\n"+
"for refreshing. The path and error are shown below.\n\n"+
"Path: %s\n\nError: %s",
statePath,
err))
return 1
}
// Build the context based on the arguments given
ctx, err := c.Context(configPath, statePath)
if err != nil {
c.Ui.Error(err.Error())
return 1
}
if !validateContext(ctx, c.Ui) {
return 1
}
state, err := ctx.Refresh()
if err != nil {
c.Ui.Error(fmt.Sprintf("Error refreshing state: %s", err))
return 1
}
log.Printf("[INFO] Writing state output to: %s", stateOutPath)
f, err := os.Create(stateOutPath)
if err == nil {
defer f.Close()
err = terraform.WriteState(state, f)
}
if err != nil {
c.Ui.Error(fmt.Sprintf("Error writing state file: %s", err))
return 1
}
return 0
}
func (c *RefreshCommand) Help() string {
helpText := `
Usage: terraform refresh [options] [dir]
Update the state file of your infrastructure with metadata that matches
the physical resources they are tracking.
This will not modify your infrastructure, but it can modify your
state file to update metadata. This metadata might cause new changes
to occur when you generate a plan or call apply next.
Options:
-no-color If specified, output won't contain any color.
-state=path Path to read and save state (unless state-out
is specified). Defaults to "terraform.tfstate".
-state-out=path Path to write updated state file. By default, the
"-state" path will be used.
`
return strings.TrimSpace(helpText)
}
func (c *RefreshCommand) Synopsis() string {
return "Update local state file against real resources"
}