command/taint: -allow-missing
This commit is contained in:
parent
d43c88f5f3
commit
d411e2939f
|
@ -15,8 +15,10 @@ type TaintCommand struct {
|
|||
func (c *TaintCommand) Run(args []string) int {
|
||||
args = c.Meta.process(args, false)
|
||||
|
||||
var allowMissing bool
|
||||
var module string
|
||||
cmdFlags := c.Meta.flagSet("taint")
|
||||
cmdFlags.BoolVar(&allowMissing, "allow-missing", false, "module")
|
||||
cmdFlags.StringVar(&module, "module", "", "module")
|
||||
cmdFlags.StringVar(&c.Meta.statePath, "state", DefaultStateFilename, "path")
|
||||
cmdFlags.StringVar(&c.Meta.stateOutPath, "state-out", "", "path")
|
||||
|
@ -33,7 +35,13 @@ func (c *TaintCommand) Run(args []string) int {
|
|||
cmdFlags.Usage()
|
||||
return 1
|
||||
}
|
||||
|
||||
name := args[0]
|
||||
if module == "" {
|
||||
module = "root"
|
||||
} else {
|
||||
module = "root." + module
|
||||
}
|
||||
|
||||
// Get the state that we'll be modifying
|
||||
state, err := c.State()
|
||||
|
@ -45,6 +53,10 @@ func (c *TaintCommand) Run(args []string) int {
|
|||
// Get the actual state structure
|
||||
s := state.State()
|
||||
if s.Empty() {
|
||||
if allowMissing {
|
||||
return c.allowMissingExit(name, module)
|
||||
}
|
||||
|
||||
c.Ui.Error(fmt.Sprintf(
|
||||
"The state is empty. The most common reason for this is that\n" +
|
||||
"an invalid state file path was given or Terraform has never\n " +
|
||||
|
@ -54,14 +66,13 @@ func (c *TaintCommand) Run(args []string) int {
|
|||
}
|
||||
|
||||
// Get the proper module we want to taint
|
||||
if module == "" {
|
||||
module = "root"
|
||||
} else {
|
||||
module = "root." + module
|
||||
}
|
||||
modPath := strings.Split(module, ".")
|
||||
mod := s.ModuleByPath(modPath)
|
||||
if mod == nil {
|
||||
if allowMissing {
|
||||
return c.allowMissingExit(name, module)
|
||||
}
|
||||
|
||||
c.Ui.Error(fmt.Sprintf(
|
||||
"The module %s could not be found. There is nothing to taint.",
|
||||
module))
|
||||
|
@ -70,6 +81,10 @@ func (c *TaintCommand) Run(args []string) int {
|
|||
|
||||
// If there are no resources in this module, it is an error
|
||||
if len(mod.Resources) == 0 {
|
||||
if allowMissing {
|
||||
return c.allowMissingExit(name, module)
|
||||
}
|
||||
|
||||
c.Ui.Error(fmt.Sprintf(
|
||||
"The module %s has no resources. There is nothing to taint.",
|
||||
module))
|
||||
|
@ -79,6 +94,10 @@ func (c *TaintCommand) Run(args []string) int {
|
|||
// Get the resource we're looking for
|
||||
rs, ok := mod.Resources[name]
|
||||
if !ok {
|
||||
if allowMissing {
|
||||
return c.allowMissingExit(name, module)
|
||||
}
|
||||
|
||||
c.Ui.Error(fmt.Sprintf(
|
||||
"The resource %s couldn't be found in the module %s.",
|
||||
name,
|
||||
|
@ -116,6 +135,9 @@ Usage: terraform taint [options] name
|
|||
|
||||
Options:
|
||||
|
||||
-allow-missing If specified, the command will succeed (exit code 0)
|
||||
even if the resource is missing.
|
||||
|
||||
-backup=path Path to backup the existing state file before
|
||||
modifying. Defaults to the "-state-out" path with
|
||||
".backup" extension. Set to "-" to disable backup.
|
||||
|
@ -139,3 +161,11 @@ Options:
|
|||
func (c *TaintCommand) Synopsis() string {
|
||||
return "Manually mark a resource for recreation"
|
||||
}
|
||||
|
||||
func (c *TaintCommand) allowMissingExit(name, module string) int {
|
||||
c.Ui.Output(fmt.Sprintf(
|
||||
"The resource %s in the module %s was not found, but\n"+
|
||||
"-allow-missing is set, so we're exiting successfully.",
|
||||
name, module))
|
||||
return 0
|
||||
}
|
||||
|
|
|
@ -187,6 +187,75 @@ func TestTaint_defaultState(t *testing.T) {
|
|||
testStateOutput(t, path, testTaintStr)
|
||||
}
|
||||
|
||||
func TestTaint_missing(t *testing.T) {
|
||||
state := &terraform.State{
|
||||
Modules: []*terraform.ModuleState{
|
||||
&terraform.ModuleState{
|
||||
Path: []string{"root"},
|
||||
Resources: map[string]*terraform.ResourceState{
|
||||
"test_instance.foo": &terraform.ResourceState{
|
||||
Type: "test_instance",
|
||||
Primary: &terraform.InstanceState{
|
||||
ID: "bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
statePath := testStateFile(t, state)
|
||||
|
||||
ui := new(cli.MockUi)
|
||||
c := &TaintCommand{
|
||||
Meta: Meta{
|
||||
Ui: ui,
|
||||
},
|
||||
}
|
||||
|
||||
args := []string{
|
||||
"-state", statePath,
|
||||
"test_instance.bar",
|
||||
}
|
||||
if code := c.Run(args); code == 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.OutputWriter.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestTaint_missingAllow(t *testing.T) {
|
||||
state := &terraform.State{
|
||||
Modules: []*terraform.ModuleState{
|
||||
&terraform.ModuleState{
|
||||
Path: []string{"root"},
|
||||
Resources: map[string]*terraform.ResourceState{
|
||||
"test_instance.foo": &terraform.ResourceState{
|
||||
Type: "test_instance",
|
||||
Primary: &terraform.InstanceState{
|
||||
ID: "bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
statePath := testStateFile(t, state)
|
||||
|
||||
ui := new(cli.MockUi)
|
||||
c := &TaintCommand{
|
||||
Meta: Meta{
|
||||
Ui: ui,
|
||||
},
|
||||
}
|
||||
|
||||
args := []string{
|
||||
"-allow-missing",
|
||||
"-state", statePath,
|
||||
"test_instance.bar",
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestTaint_stateOut(t *testing.T) {
|
||||
// Get a temp cwd
|
||||
tmp, cwd := testCwd(t)
|
||||
|
|
|
@ -40,6 +40,10 @@ The format of this argument is `TYPE.NAME`, such as `aws_instance.foo`.
|
|||
|
||||
The command-line flags are all optional. The list of available flags are:
|
||||
|
||||
* `-allow-missing` - If specified, the command will succeed (exit code 0)
|
||||
even if the resource is missing. The command can still error, but only
|
||||
in critically erroneous cases.
|
||||
|
||||
* `-backup=path` - Path to the backup file. Defaults to `-state-out` with
|
||||
the ".backup" extension. Disabled by setting to "-".
|
||||
|
||||
|
|
Loading…
Reference in New Issue