remove invalid destroy provisioner tests
Remove all the destroy provisioner tests that are testing what is no longer allowed. Add missing state dependencies to remaining tests that require it.
This commit is contained in:
parent
9edb719aaa
commit
a4bc91abeb
|
@ -290,35 +290,26 @@ func TestContext2Apply_resourceDependsOnModuleStateOnly(t *testing.T) {
|
||||||
p := testProvider("aws")
|
p := testProvider("aws")
|
||||||
p.DiffFn = testDiffFn
|
p.DiffFn = testDiffFn
|
||||||
|
|
||||||
state := MustShimLegacyState(&State{
|
state := states.NewState()
|
||||||
Modules: []*ModuleState{
|
root := state.EnsureModule(addrs.RootModuleInstance)
|
||||||
&ModuleState{
|
root.SetResourceInstanceCurrent(
|
||||||
Path: rootModulePath,
|
mustResourceInstanceAddr("aws_instance.a").Resource,
|
||||||
Resources: map[string]*ResourceState{
|
&states.ResourceInstanceObjectSrc{
|
||||||
"aws_instance.a": &ResourceState{
|
Status: states.ObjectReady,
|
||||||
Type: "aws_instance",
|
AttrsJSON: []byte(`{"id":"parent"}`),
|
||||||
Primary: &InstanceState{
|
Dependencies: []addrs.AbsResource{mustResourceAddr("module.child.aws_instance.child")},
|
||||||
ID: "parent",
|
|
||||||
},
|
|
||||||
Dependencies: []string{"module.child"},
|
|
||||||
Provider: "provider.aws",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
&ModuleState{
|
|
||||||
Path: []string{"root", "child"},
|
|
||||||
Resources: map[string]*ResourceState{
|
|
||||||
"aws_instance.child": &ResourceState{
|
|
||||||
Type: "aws_instance",
|
|
||||||
Primary: &InstanceState{
|
|
||||||
ID: "child",
|
|
||||||
},
|
|
||||||
Provider: "provider.aws",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
})
|
mustProviderConfig("provider.aws"),
|
||||||
|
)
|
||||||
|
child := state.EnsureModule(addrs.RootModuleInstance.Child("child", addrs.NoKey))
|
||||||
|
child.SetResourceInstanceCurrent(
|
||||||
|
mustResourceInstanceAddr("aws_instance.child").Resource,
|
||||||
|
&states.ResourceInstanceObjectSrc{
|
||||||
|
Status: states.ObjectReady,
|
||||||
|
AttrsJSON: []byte(`{"id":"child"}`),
|
||||||
|
},
|
||||||
|
mustProviderConfig("provider.aws"),
|
||||||
|
)
|
||||||
|
|
||||||
{
|
{
|
||||||
// verify the apply happens in the correct order
|
// verify the apply happens in the correct order
|
||||||
|
@ -1264,30 +1255,26 @@ func testContext2Apply_destroyDependsOn(t *testing.T) {
|
||||||
p := testProvider("aws")
|
p := testProvider("aws")
|
||||||
p.ApplyFn = testApplyFn
|
p.ApplyFn = testApplyFn
|
||||||
p.DiffFn = testDiffFn
|
p.DiffFn = testDiffFn
|
||||||
state := MustShimLegacyState(&State{
|
|
||||||
Modules: []*ModuleState{
|
|
||||||
&ModuleState{
|
|
||||||
Path: rootModulePath,
|
|
||||||
Resources: map[string]*ResourceState{
|
|
||||||
"aws_instance.foo": &ResourceState{
|
|
||||||
Type: "aws_instance",
|
|
||||||
Primary: &InstanceState{
|
|
||||||
ID: "foo",
|
|
||||||
Attributes: map[string]string{},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
"aws_instance.bar": &ResourceState{
|
state := states.NewState()
|
||||||
Type: "aws_instance",
|
root := state.EnsureModule(addrs.RootModuleInstance)
|
||||||
Primary: &InstanceState{
|
root.SetResourceInstanceCurrent(
|
||||||
ID: "bar",
|
mustResourceInstanceAddr("aws_instance.bar").Resource,
|
||||||
Attributes: map[string]string{},
|
&states.ResourceInstanceObjectSrc{
|
||||||
},
|
Status: states.ObjectReady,
|
||||||
},
|
AttrsJSON: []byte(`{"id":"bar"}`),
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
})
|
mustProviderConfig("provider.aws"),
|
||||||
|
)
|
||||||
|
root.SetResourceInstanceCurrent(
|
||||||
|
mustResourceInstanceAddr("aws_instance.foo").Resource,
|
||||||
|
&states.ResourceInstanceObjectSrc{
|
||||||
|
Status: states.ObjectReady,
|
||||||
|
AttrsJSON: []byte(`{"id":"foo"}`),
|
||||||
|
Dependencies: []addrs.AbsResource{mustResourceAddr("aws_instance.bar")},
|
||||||
|
},
|
||||||
|
mustProviderConfig("provider.aws"),
|
||||||
|
)
|
||||||
|
|
||||||
// Record the order we see Apply
|
// Record the order we see Apply
|
||||||
var actual []string
|
var actual []string
|
||||||
|
@ -1329,34 +1316,6 @@ func testContext2Apply_destroyDependsOn(t *testing.T) {
|
||||||
// Test that destroy ordering is correct with dependencies only
|
// Test that destroy ordering is correct with dependencies only
|
||||||
// in the state.
|
// in the state.
|
||||||
func TestContext2Apply_destroyDependsOnStateOnly(t *testing.T) {
|
func TestContext2Apply_destroyDependsOnStateOnly(t *testing.T) {
|
||||||
legacyState := MustShimLegacyState(&State{
|
|
||||||
Modules: []*ModuleState{
|
|
||||||
&ModuleState{
|
|
||||||
Path: rootModulePath,
|
|
||||||
Resources: map[string]*ResourceState{
|
|
||||||
"aws_instance.foo": &ResourceState{
|
|
||||||
Type: "aws_instance",
|
|
||||||
Primary: &InstanceState{
|
|
||||||
ID: "foo",
|
|
||||||
Attributes: map[string]string{},
|
|
||||||
},
|
|
||||||
Provider: "provider.aws",
|
|
||||||
},
|
|
||||||
|
|
||||||
"aws_instance.bar": &ResourceState{
|
|
||||||
Type: "aws_instance",
|
|
||||||
Primary: &InstanceState{
|
|
||||||
ID: "bar",
|
|
||||||
Attributes: map[string]string{},
|
|
||||||
},
|
|
||||||
Dependencies: []string{"aws_instance.foo"},
|
|
||||||
Provider: "provider.aws",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
newState := states.NewState()
|
newState := states.NewState()
|
||||||
root := newState.EnsureModule(addrs.RootModuleInstance)
|
root := newState.EnsureModule(addrs.RootModuleInstance)
|
||||||
root.SetResourceInstanceCurrent(
|
root.SetResourceInstanceCurrent(
|
||||||
|
@ -1404,9 +1363,6 @@ func TestContext2Apply_destroyDependsOnStateOnly(t *testing.T) {
|
||||||
// It is possible for this to be racy, so we loop a number of times
|
// It is possible for this to be racy, so we loop a number of times
|
||||||
// just to check.
|
// just to check.
|
||||||
for i := 0; i < 10; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
t.Run("legacy", func(t *testing.T) {
|
|
||||||
testContext2Apply_destroyDependsOnStateOnly(t, legacyState)
|
|
||||||
})
|
|
||||||
t.Run("new", func(t *testing.T) {
|
t.Run("new", func(t *testing.T) {
|
||||||
testContext2Apply_destroyDependsOnStateOnly(t, newState)
|
testContext2Apply_destroyDependsOnStateOnly(t, newState)
|
||||||
})
|
})
|
||||||
|
@ -1458,34 +1414,6 @@ func testContext2Apply_destroyDependsOnStateOnly(t *testing.T, state *states.Sta
|
||||||
// Test that destroy ordering is correct with dependencies only
|
// Test that destroy ordering is correct with dependencies only
|
||||||
// in the state within a module (GH-11749)
|
// in the state within a module (GH-11749)
|
||||||
func TestContext2Apply_destroyDependsOnStateOnlyModule(t *testing.T) {
|
func TestContext2Apply_destroyDependsOnStateOnlyModule(t *testing.T) {
|
||||||
legacyState := MustShimLegacyState(&State{
|
|
||||||
Modules: []*ModuleState{
|
|
||||||
&ModuleState{
|
|
||||||
Path: []string{"root", "child"},
|
|
||||||
Resources: map[string]*ResourceState{
|
|
||||||
"aws_instance.foo": &ResourceState{
|
|
||||||
Type: "aws_instance",
|
|
||||||
Primary: &InstanceState{
|
|
||||||
ID: "foo",
|
|
||||||
Attributes: map[string]string{},
|
|
||||||
},
|
|
||||||
Provider: "provider.aws",
|
|
||||||
},
|
|
||||||
|
|
||||||
"aws_instance.bar": &ResourceState{
|
|
||||||
Type: "aws_instance",
|
|
||||||
Primary: &InstanceState{
|
|
||||||
ID: "bar",
|
|
||||||
Attributes: map[string]string{},
|
|
||||||
},
|
|
||||||
Dependencies: []string{"aws_instance.foo"},
|
|
||||||
Provider: "provider.aws",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
newState := states.NewState()
|
newState := states.NewState()
|
||||||
child := newState.EnsureModule(addrs.RootModuleInstance.Child("child", addrs.NoKey))
|
child := newState.EnsureModule(addrs.RootModuleInstance.Child("child", addrs.NoKey))
|
||||||
child.SetResourceInstanceCurrent(
|
child.SetResourceInstanceCurrent(
|
||||||
|
@ -1533,9 +1461,6 @@ func TestContext2Apply_destroyDependsOnStateOnlyModule(t *testing.T) {
|
||||||
// It is possible for this to be racy, so we loop a number of times
|
// It is possible for this to be racy, so we loop a number of times
|
||||||
// just to check.
|
// just to check.
|
||||||
for i := 0; i < 10; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
t.Run("legacy", func(t *testing.T) {
|
|
||||||
testContext2Apply_destroyDependsOnStateOnlyModule(t, legacyState)
|
|
||||||
})
|
|
||||||
t.Run("new", func(t *testing.T) {
|
t.Run("new", func(t *testing.T) {
|
||||||
testContext2Apply_destroyDependsOnStateOnlyModule(t, newState)
|
testContext2Apply_destroyDependsOnStateOnlyModule(t, newState)
|
||||||
})
|
})
|
||||||
|
@ -2118,72 +2043,6 @@ aws_instance.foo:
|
||||||
`)
|
`)
|
||||||
}
|
}
|
||||||
|
|
||||||
// for_each values cannot be used in the provisioner during destroy.
|
|
||||||
// There may be a way to handle this, but for now make sure we print an error
|
|
||||||
// rather than crashing with an invalid config.
|
|
||||||
func TestContext2Apply_provisionerDestroyForEach(t *testing.T) {
|
|
||||||
m := testModule(t, "apply-provisioner-each")
|
|
||||||
p := testProvider("aws")
|
|
||||||
pr := testProvisioner()
|
|
||||||
p.DiffFn = testDiffFn
|
|
||||||
p.ApplyFn = testApplyFn
|
|
||||||
|
|
||||||
s := &states.State{
|
|
||||||
Modules: map[string]*states.Module{
|
|
||||||
"": &states.Module{
|
|
||||||
Resources: map[string]*states.Resource{
|
|
||||||
"aws_instance.bar": &states.Resource{
|
|
||||||
Addr: addrs.Resource{Mode: 77, Type: "aws_instance", Name: "bar"},
|
|
||||||
EachMode: states.EachMap,
|
|
||||||
Instances: map[addrs.InstanceKey]*states.ResourceInstance{
|
|
||||||
addrs.StringKey("a"): &states.ResourceInstance{
|
|
||||||
Current: &states.ResourceInstanceObjectSrc{
|
|
||||||
AttrsJSON: []byte(`{"foo":"bar","id":"foo"}`),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
addrs.StringKey("b"): &states.ResourceInstance{
|
|
||||||
Current: &states.ResourceInstanceObjectSrc{
|
|
||||||
AttrsJSON: []byte(`{"foo":"bar","id":"foo"}`),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProviderConfig: addrs.AbsProviderConfig{
|
|
||||||
Module: addrs.ModuleInstance(nil),
|
|
||||||
Provider: addrs.NewLegacyProvider("aws"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx := testContext2(t, &ContextOpts{
|
|
||||||
Config: m,
|
|
||||||
ProviderResolver: providers.ResolverFixed(
|
|
||||||
map[addrs.Provider]providers.Factory{
|
|
||||||
addrs.NewLegacyProvider("aws"): testProviderFuncFixed(p),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
Provisioners: map[string]ProvisionerFactory{
|
|
||||||
"shell": testProvisionerFuncFixed(pr),
|
|
||||||
},
|
|
||||||
State: s,
|
|
||||||
Destroy: true,
|
|
||||||
})
|
|
||||||
|
|
||||||
if _, diags := ctx.Plan(); diags.HasErrors() {
|
|
||||||
t.Fatalf("plan errors: %s", diags.Err())
|
|
||||||
}
|
|
||||||
|
|
||||||
_, diags := ctx.Apply()
|
|
||||||
if diags == nil {
|
|
||||||
t.Fatal("should error")
|
|
||||||
}
|
|
||||||
if !strings.Contains(diags.Err().Error(), "each.value cannot be used in this context") {
|
|
||||||
t.Fatal("unexpected error:", diags.Err())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContext2Apply_cancelProvisioner(t *testing.T) {
|
func TestContext2Apply_cancelProvisioner(t *testing.T) {
|
||||||
m := testModule(t, "apply-cancel-provisioner")
|
m := testModule(t, "apply-cancel-provisioner")
|
||||||
p := testProvider("aws")
|
p := testProvider("aws")
|
||||||
|
@ -2831,30 +2690,26 @@ func TestContext2Apply_moduleDestroyOrder(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
state := MustShimLegacyState(&State{
|
state := states.NewState()
|
||||||
Modules: []*ModuleState{
|
child := state.EnsureModule(addrs.RootModuleInstance.Child("child", addrs.NoKey))
|
||||||
&ModuleState{
|
child.SetResourceInstanceCurrent(
|
||||||
Path: rootModulePath,
|
mustResourceInstanceAddr("aws_instance.a").Resource,
|
||||||
Resources: map[string]*ResourceState{
|
&states.ResourceInstanceObjectSrc{
|
||||||
"aws_instance.b": resourceState("aws_instance", "b"),
|
Status: states.ObjectReady,
|
||||||
},
|
AttrsJSON: []byte(`{"id":"a"}`),
|
||||||
},
|
|
||||||
|
|
||||||
&ModuleState{
|
|
||||||
Path: []string{"root", "child"},
|
|
||||||
Resources: map[string]*ResourceState{
|
|
||||||
"aws_instance.a": resourceState("aws_instance", "a"),
|
|
||||||
},
|
|
||||||
Outputs: map[string]*OutputState{
|
|
||||||
"a_output": &OutputState{
|
|
||||||
Type: "string",
|
|
||||||
Sensitive: false,
|
|
||||||
Value: "a",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
})
|
mustProviderConfig("provider.aws"),
|
||||||
|
)
|
||||||
|
root := state.EnsureModule(addrs.RootModuleInstance)
|
||||||
|
root.SetResourceInstanceCurrent(
|
||||||
|
mustResourceInstanceAddr("aws_instance.b").Resource,
|
||||||
|
&states.ResourceInstanceObjectSrc{
|
||||||
|
Status: states.ObjectReady,
|
||||||
|
AttrsJSON: []byte(`{"id":"b"}`),
|
||||||
|
Dependencies: []addrs.AbsResource{mustResourceAddr("module.child.aws_instance.a")},
|
||||||
|
},
|
||||||
|
mustProviderConfig("provider.aws"),
|
||||||
|
)
|
||||||
|
|
||||||
ctx := testContext2(t, &ContextOpts{
|
ctx := testContext2(t, &ContextOpts{
|
||||||
Config: m,
|
Config: m,
|
||||||
|
@ -5763,196 +5618,6 @@ aws_instance.foo:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestContext2Apply_provisionerDestroyModule(t *testing.T) {
|
|
||||||
m := testModule(t, "apply-provisioner-destroy-module")
|
|
||||||
p := testProvider("aws")
|
|
||||||
pr := testProvisioner()
|
|
||||||
p.ApplyFn = testApplyFn
|
|
||||||
p.DiffFn = testDiffFn
|
|
||||||
pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
|
|
||||||
val, ok := c.Config["command"]
|
|
||||||
if !ok || val != "value" {
|
|
||||||
t.Fatalf("bad value for foo: %v %#v", val, c)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
state := MustShimLegacyState(&State{
|
|
||||||
Modules: []*ModuleState{
|
|
||||||
&ModuleState{
|
|
||||||
Path: []string{"root", "child"},
|
|
||||||
Resources: map[string]*ResourceState{
|
|
||||||
"aws_instance.foo": &ResourceState{
|
|
||||||
Type: "aws_instance",
|
|
||||||
Primary: &InstanceState{
|
|
||||||
ID: "bar",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
ctx := testContext2(t, &ContextOpts{
|
|
||||||
Config: m,
|
|
||||||
State: state,
|
|
||||||
Destroy: true,
|
|
||||||
ProviderResolver: providers.ResolverFixed(
|
|
||||||
map[addrs.Provider]providers.Factory{
|
|
||||||
addrs.NewLegacyProvider("aws"): testProviderFuncFixed(p),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
Provisioners: map[string]ProvisionerFactory{
|
|
||||||
"shell": testProvisionerFuncFixed(pr),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
if _, diags := ctx.Plan(); diags.HasErrors() {
|
|
||||||
t.Fatalf("plan errors: %s", diags.Err())
|
|
||||||
}
|
|
||||||
|
|
||||||
state, diags := ctx.Apply()
|
|
||||||
if diags.HasErrors() {
|
|
||||||
t.Fatalf("diags: %s", diags.Err())
|
|
||||||
}
|
|
||||||
|
|
||||||
checkStateString(t, state, `<no state>`)
|
|
||||||
|
|
||||||
// Verify apply was invoked
|
|
||||||
if !pr.ProvisionResourceCalled {
|
|
||||||
t.Fatalf("provisioner not invoked")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContext2Apply_provisionerDestroyRef(t *testing.T) {
|
|
||||||
m := testModule(t, "apply-provisioner-destroy-ref")
|
|
||||||
p := testProvider("aws")
|
|
||||||
pr := testProvisioner()
|
|
||||||
p.ApplyFn = testApplyFn
|
|
||||||
p.DiffFn = testDiffFn
|
|
||||||
pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
|
|
||||||
val, ok := c.Config["command"]
|
|
||||||
if !ok || val != "hello" {
|
|
||||||
return fmt.Errorf("bad value for command: %v %#v", val, c)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
state := MustShimLegacyState(&State{
|
|
||||||
Modules: []*ModuleState{
|
|
||||||
&ModuleState{
|
|
||||||
Path: rootModulePath,
|
|
||||||
Resources: map[string]*ResourceState{
|
|
||||||
"aws_instance.bar": &ResourceState{
|
|
||||||
Type: "aws_instance",
|
|
||||||
Primary: &InstanceState{
|
|
||||||
ID: "bar",
|
|
||||||
Attributes: map[string]string{
|
|
||||||
"value": "hello",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Provider: "provider.aws",
|
|
||||||
},
|
|
||||||
|
|
||||||
"aws_instance.foo": &ResourceState{
|
|
||||||
Type: "aws_instance",
|
|
||||||
Primary: &InstanceState{
|
|
||||||
ID: "bar",
|
|
||||||
},
|
|
||||||
Provider: "provider.aws",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
ctx := testContext2(t, &ContextOpts{
|
|
||||||
Config: m,
|
|
||||||
State: state,
|
|
||||||
Destroy: true,
|
|
||||||
ProviderResolver: providers.ResolverFixed(
|
|
||||||
map[addrs.Provider]providers.Factory{
|
|
||||||
addrs.NewLegacyProvider("aws"): testProviderFuncFixed(p),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
Provisioners: map[string]ProvisionerFactory{
|
|
||||||
"shell": testProvisionerFuncFixed(pr),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
if _, diags := ctx.Plan(); diags.HasErrors() {
|
|
||||||
t.Fatalf("plan errors: %s", diags.Err())
|
|
||||||
}
|
|
||||||
|
|
||||||
state, diags := ctx.Apply()
|
|
||||||
if diags.HasErrors() {
|
|
||||||
t.Fatalf("diags: %s", diags.Err())
|
|
||||||
}
|
|
||||||
|
|
||||||
checkStateString(t, state, `<no state>`)
|
|
||||||
|
|
||||||
// Verify apply was invoked
|
|
||||||
if !pr.ProvisionResourceCalled {
|
|
||||||
t.Fatalf("provisioner not invoked")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test that a destroy provisioner referencing an invalid key errors.
|
|
||||||
func TestContext2Apply_provisionerDestroyRefInvalid(t *testing.T) {
|
|
||||||
m := testModule(t, "apply-provisioner-destroy-ref-invalid")
|
|
||||||
p := testProvider("aws")
|
|
||||||
pr := testProvisioner()
|
|
||||||
p.ApplyFn = testApplyFn
|
|
||||||
p.DiffFn = testDiffFn
|
|
||||||
pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
state := MustShimLegacyState(&State{
|
|
||||||
Modules: []*ModuleState{
|
|
||||||
&ModuleState{
|
|
||||||
Path: rootModulePath,
|
|
||||||
Resources: map[string]*ResourceState{
|
|
||||||
"aws_instance.bar": &ResourceState{
|
|
||||||
Type: "aws_instance",
|
|
||||||
Primary: &InstanceState{
|
|
||||||
ID: "bar",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
"aws_instance.foo": &ResourceState{
|
|
||||||
Type: "aws_instance",
|
|
||||||
Primary: &InstanceState{
|
|
||||||
ID: "bar",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
ctx := testContext2(t, &ContextOpts{
|
|
||||||
Config: m,
|
|
||||||
State: state,
|
|
||||||
Destroy: true,
|
|
||||||
ProviderResolver: providers.ResolverFixed(
|
|
||||||
map[addrs.Provider]providers.Factory{
|
|
||||||
addrs.NewLegacyProvider("aws"): testProviderFuncFixed(p),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
Provisioners: map[string]ProvisionerFactory{
|
|
||||||
"shell": testProvisionerFuncFixed(pr),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
// this was an apply test, but this is now caught in Validation
|
|
||||||
if diags := ctx.Validate(); !diags.HasErrors() {
|
|
||||||
t.Fatal("expected error")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContext2Apply_provisionerResourceRef(t *testing.T) {
|
func TestContext2Apply_provisionerResourceRef(t *testing.T) {
|
||||||
m := testModule(t, "apply-provisioner-resource-ref")
|
m := testModule(t, "apply-provisioner-resource-ref")
|
||||||
p := testProvider("aws")
|
p := testProvider("aws")
|
||||||
|
@ -8350,259 +8015,32 @@ aws_instance.bar:
|
||||||
`)
|
`)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestContext2Apply_destroyProvisionerWithLocals(t *testing.T) {
|
|
||||||
m := testModule(t, "apply-provisioner-destroy-locals")
|
|
||||||
p := testProvider("aws")
|
|
||||||
p.ApplyFn = testApplyFn
|
|
||||||
p.DiffFn = testDiffFn
|
|
||||||
|
|
||||||
pr := testProvisioner()
|
|
||||||
pr.ApplyFn = func(_ *InstanceState, rc *ResourceConfig) error {
|
|
||||||
cmd, ok := rc.Get("command")
|
|
||||||
if !ok || cmd != "local" {
|
|
||||||
return fmt.Errorf("provisioner got %v:%s", ok, cmd)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
pr.GetSchemaResponse = provisioners.GetSchemaResponse{
|
|
||||||
Provisioner: &configschema.Block{
|
|
||||||
Attributes: map[string]*configschema.Attribute{
|
|
||||||
"command": {
|
|
||||||
Type: cty.String,
|
|
||||||
Required: true,
|
|
||||||
},
|
|
||||||
"when": {
|
|
||||||
Type: cty.String,
|
|
||||||
Optional: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx := testContext2(t, &ContextOpts{
|
|
||||||
Config: m,
|
|
||||||
ProviderResolver: providers.ResolverFixed(
|
|
||||||
map[addrs.Provider]providers.Factory{
|
|
||||||
addrs.NewLegacyProvider("aws"): testProviderFuncFixed(p),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
Provisioners: map[string]ProvisionerFactory{
|
|
||||||
"shell": testProvisionerFuncFixed(pr),
|
|
||||||
},
|
|
||||||
State: MustShimLegacyState(&State{
|
|
||||||
Modules: []*ModuleState{
|
|
||||||
&ModuleState{
|
|
||||||
Path: []string{"root"},
|
|
||||||
Resources: map[string]*ResourceState{
|
|
||||||
"aws_instance.foo": resourceState("aws_instance", "1234"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
Destroy: true,
|
|
||||||
// the test works without targeting, but this also tests that the local
|
|
||||||
// node isn't inadvertently pruned because of the wrong evaluation
|
|
||||||
// order.
|
|
||||||
Targets: []addrs.Targetable{
|
|
||||||
addrs.RootModuleInstance.Resource(
|
|
||||||
addrs.ManagedResourceMode, "aws_instance", "foo",
|
|
||||||
),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
if _, diags := ctx.Plan(); diags.HasErrors() {
|
|
||||||
t.Fatal(diags.Err())
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, diags := ctx.Apply(); diags.HasErrors() {
|
|
||||||
t.Fatal(diags.Err())
|
|
||||||
}
|
|
||||||
|
|
||||||
if !pr.ProvisionResourceCalled {
|
|
||||||
t.Fatal("provisioner not called")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// this also tests a local value in the config referencing a resource that
|
|
||||||
// wasn't in the state during destroy.
|
|
||||||
func TestContext2Apply_destroyProvisionerWithMultipleLocals(t *testing.T) {
|
|
||||||
m := testModule(t, "apply-provisioner-destroy-multiple-locals")
|
|
||||||
p := testProvider("aws")
|
|
||||||
p.ApplyFn = testApplyFn
|
|
||||||
p.DiffFn = testDiffFn
|
|
||||||
|
|
||||||
pr := testProvisioner()
|
|
||||||
pr.GetSchemaResponse = provisioners.GetSchemaResponse{
|
|
||||||
Provisioner: &configschema.Block{
|
|
||||||
Attributes: map[string]*configschema.Attribute{
|
|
||||||
"id": {
|
|
||||||
Type: cty.String,
|
|
||||||
Required: true,
|
|
||||||
},
|
|
||||||
"command": {
|
|
||||||
Type: cty.String,
|
|
||||||
Required: true,
|
|
||||||
},
|
|
||||||
"when": {
|
|
||||||
Type: cty.String,
|
|
||||||
Optional: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
pr.ApplyFn = func(is *InstanceState, rc *ResourceConfig) error {
|
|
||||||
cmd, ok := rc.Get("command")
|
|
||||||
if !ok {
|
|
||||||
return errors.New("no command in provisioner")
|
|
||||||
}
|
|
||||||
id, ok := rc.Get("id")
|
|
||||||
if !ok {
|
|
||||||
return errors.New("no id in provisioner")
|
|
||||||
}
|
|
||||||
|
|
||||||
switch id {
|
|
||||||
case "1234":
|
|
||||||
if cmd != "local" {
|
|
||||||
return fmt.Errorf("provisioner %q got:%q", is.ID, cmd)
|
|
||||||
}
|
|
||||||
case "3456":
|
|
||||||
if cmd != "1234" {
|
|
||||||
return fmt.Errorf("provisioner %q got:%q", is.ID, cmd)
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
t.Fatal("unknown instance")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx := testContext2(t, &ContextOpts{
|
|
||||||
Config: m,
|
|
||||||
ProviderResolver: providers.ResolverFixed(
|
|
||||||
map[addrs.Provider]providers.Factory{
|
|
||||||
addrs.NewLegacyProvider("aws"): testProviderFuncFixed(p),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
Provisioners: map[string]ProvisionerFactory{
|
|
||||||
"shell": testProvisionerFuncFixed(pr),
|
|
||||||
},
|
|
||||||
State: MustShimLegacyState(&State{
|
|
||||||
Modules: []*ModuleState{
|
|
||||||
&ModuleState{
|
|
||||||
Path: []string{"root"},
|
|
||||||
Resources: map[string]*ResourceState{
|
|
||||||
"aws_instance.foo": resourceState("aws_instance", "1234"),
|
|
||||||
"aws_instance.bar": resourceState("aws_instance", "3456"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
Destroy: true,
|
|
||||||
})
|
|
||||||
|
|
||||||
if _, diags := ctx.Plan(); diags.HasErrors() {
|
|
||||||
t.Fatal(diags.Err())
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, diags := ctx.Apply(); diags.HasErrors() {
|
|
||||||
t.Fatal(diags.Err())
|
|
||||||
}
|
|
||||||
|
|
||||||
if !pr.ProvisionResourceCalled {
|
|
||||||
t.Fatal("provisioner not called")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContext2Apply_destroyProvisionerWithOutput(t *testing.T) {
|
|
||||||
m := testModule(t, "apply-provisioner-destroy-outputs")
|
|
||||||
p := testProvider("aws")
|
|
||||||
p.ApplyFn = testApplyFn
|
|
||||||
p.DiffFn = testDiffFn
|
|
||||||
|
|
||||||
pr := testProvisioner()
|
|
||||||
pr.ApplyFn = func(is *InstanceState, rc *ResourceConfig) error {
|
|
||||||
cmd, ok := rc.Get("command")
|
|
||||||
if !ok || cmd != "3" {
|
|
||||||
return fmt.Errorf("provisioner for %s got %v:%s", is.ID, ok, cmd)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
ctx := testContext2(t, &ContextOpts{
|
|
||||||
Config: m,
|
|
||||||
ProviderResolver: providers.ResolverFixed(
|
|
||||||
map[addrs.Provider]providers.Factory{
|
|
||||||
addrs.NewLegacyProvider("aws"): testProviderFuncFixed(p),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
Provisioners: map[string]ProvisionerFactory{
|
|
||||||
"shell": testProvisionerFuncFixed(pr),
|
|
||||||
},
|
|
||||||
State: MustShimLegacyState(&State{
|
|
||||||
Modules: []*ModuleState{
|
|
||||||
&ModuleState{
|
|
||||||
Path: []string{"root"},
|
|
||||||
Resources: map[string]*ResourceState{
|
|
||||||
"aws_instance.foo": resourceState("aws_instance", "1"),
|
|
||||||
},
|
|
||||||
Outputs: map[string]*OutputState{
|
|
||||||
"value": {
|
|
||||||
Type: "string",
|
|
||||||
Value: "3",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
&ModuleState{
|
|
||||||
Path: []string{"root", "mod"},
|
|
||||||
Resources: map[string]*ResourceState{
|
|
||||||
"aws_instance.baz": resourceState("aws_instance", "3"),
|
|
||||||
},
|
|
||||||
// state needs to be properly initialized
|
|
||||||
Outputs: map[string]*OutputState{},
|
|
||||||
},
|
|
||||||
&ModuleState{
|
|
||||||
Path: []string{"root", "mod2"},
|
|
||||||
Resources: map[string]*ResourceState{
|
|
||||||
"aws_instance.bar": resourceState("aws_instance", "2"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
Destroy: true,
|
|
||||||
|
|
||||||
// targeting the source of the value used by all resources should still
|
|
||||||
// destroy them all.
|
|
||||||
Targets: []addrs.Targetable{
|
|
||||||
addrs.RootModuleInstance.Child("mod", addrs.NoKey).Resource(
|
|
||||||
addrs.ManagedResourceMode, "aws_instance", "baz",
|
|
||||||
),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
if _, diags := ctx.Plan(); diags.HasErrors() {
|
|
||||||
t.Fatal(diags.Err())
|
|
||||||
}
|
|
||||||
|
|
||||||
state, diags := ctx.Apply()
|
|
||||||
if diags.HasErrors() {
|
|
||||||
t.Fatal(diags.Err())
|
|
||||||
}
|
|
||||||
if !pr.ProvisionResourceCalled {
|
|
||||||
t.Fatal("provisioner not called")
|
|
||||||
}
|
|
||||||
|
|
||||||
// confirm all outputs were removed too
|
|
||||||
for _, mod := range state.Modules {
|
|
||||||
if len(mod.OutputValues) > 0 {
|
|
||||||
t.Fatalf("output left in module state: %#v\n", mod)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContext2Apply_targetedDestroyCountDeps(t *testing.T) {
|
func TestContext2Apply_targetedDestroyCountDeps(t *testing.T) {
|
||||||
m := testModule(t, "apply-destroy-targeted-count")
|
m := testModule(t, "apply-destroy-targeted-count")
|
||||||
p := testProvider("aws")
|
p := testProvider("aws")
|
||||||
p.ApplyFn = testApplyFn
|
p.ApplyFn = testApplyFn
|
||||||
p.DiffFn = testDiffFn
|
p.DiffFn = testDiffFn
|
||||||
|
|
||||||
|
state := states.NewState()
|
||||||
|
root := state.EnsureModule(addrs.RootModuleInstance)
|
||||||
|
root.SetResourceInstanceCurrent(
|
||||||
|
mustResourceInstanceAddr("aws_instance.foo").Resource,
|
||||||
|
&states.ResourceInstanceObjectSrc{
|
||||||
|
Status: states.ObjectReady,
|
||||||
|
AttrsJSON: []byte(`{"id":"i-bcd345"}`),
|
||||||
|
},
|
||||||
|
mustProviderConfig("provider.aws"),
|
||||||
|
)
|
||||||
|
root.SetResourceInstanceCurrent(
|
||||||
|
mustResourceInstanceAddr("aws_instance.bar").Resource,
|
||||||
|
&states.ResourceInstanceObjectSrc{
|
||||||
|
Status: states.ObjectReady,
|
||||||
|
AttrsJSON: []byte(`{"id":"i-abc123"}`),
|
||||||
|
Dependencies: []addrs.AbsResource{mustResourceAddr("aws_instance.foo")},
|
||||||
|
},
|
||||||
|
mustProviderConfig("provider.aws"),
|
||||||
|
)
|
||||||
|
|
||||||
ctx := testContext2(t, &ContextOpts{
|
ctx := testContext2(t, &ContextOpts{
|
||||||
Config: m,
|
Config: m,
|
||||||
ProviderResolver: providers.ResolverFixed(
|
ProviderResolver: providers.ResolverFixed(
|
||||||
|
@ -8610,17 +8048,7 @@ func TestContext2Apply_targetedDestroyCountDeps(t *testing.T) {
|
||||||
addrs.NewLegacyProvider("aws"): testProviderFuncFixed(p),
|
addrs.NewLegacyProvider("aws"): testProviderFuncFixed(p),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
State: MustShimLegacyState(&State{
|
State: state,
|
||||||
Modules: []*ModuleState{
|
|
||||||
&ModuleState{
|
|
||||||
Path: rootModulePath,
|
|
||||||
Resources: map[string]*ResourceState{
|
|
||||||
"aws_instance.foo": resourceState("aws_instance", "i-bcd345"),
|
|
||||||
"aws_instance.bar": resourceState("aws_instance", "i-abc123"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
Targets: []addrs.Targetable{
|
Targets: []addrs.Targetable{
|
||||||
addrs.RootModuleInstance.Resource(
|
addrs.RootModuleInstance.Resource(
|
||||||
addrs.ManagedResourceMode, "aws_instance", "foo",
|
addrs.ManagedResourceMode, "aws_instance", "foo",
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
locals {
|
|
||||||
value = "local"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "aws_instance" "foo" {
|
|
||||||
provisioner "shell" {
|
|
||||||
command = "${local.value}"
|
|
||||||
when = "create"
|
|
||||||
}
|
|
||||||
provisioner "shell" {
|
|
||||||
command = "${local.value}"
|
|
||||||
when = "destroy"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
variable "key" {}
|
|
||||||
|
|
||||||
resource "aws_instance" "foo" {
|
|
||||||
foo = "bar"
|
|
||||||
|
|
||||||
provisioner "shell" {
|
|
||||||
command = "${var.key}"
|
|
||||||
when = "destroy"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +0,0 @@
|
||||||
module "child" {
|
|
||||||
source = "./child"
|
|
||||||
key = "value"
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
locals {
|
|
||||||
value = "local"
|
|
||||||
foo_id = aws_instance.foo.id
|
|
||||||
|
|
||||||
// baz is not in the state during destroy, but this is a valid config that
|
|
||||||
// should not fail.
|
|
||||||
baz_id = aws_instance.baz.id
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "aws_instance" "baz" {}
|
|
||||||
|
|
||||||
resource "aws_instance" "foo" {
|
|
||||||
provisioner "shell" {
|
|
||||||
id = self.id
|
|
||||||
command = local.value
|
|
||||||
when = "destroy"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "aws_instance" "bar" {
|
|
||||||
provisioner "shell" {
|
|
||||||
id = self.id
|
|
||||||
command = local.foo_id
|
|
||||||
when = "destroy"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
module "mod" {
|
|
||||||
source = "./mod"
|
|
||||||
}
|
|
||||||
|
|
||||||
locals {
|
|
||||||
value = "${module.mod.value}"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "aws_instance" "foo" {
|
|
||||||
provisioner "shell" {
|
|
||||||
command = "${local.value}"
|
|
||||||
when = "destroy"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module "mod2" {
|
|
||||||
source = "./mod2"
|
|
||||||
value = "${module.mod.value}"
|
|
||||||
}
|
|
||||||
|
|
||||||
output "value" {
|
|
||||||
value = "${local.value}"
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
output "value" {
|
|
||||||
value = "${aws_instance.baz.id}"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "aws_instance" "baz" {}
|
|
|
@ -1,10 +0,0 @@
|
||||||
variable "value" {
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "aws_instance" "bar" {
|
|
||||||
provisioner "shell" {
|
|
||||||
command = "${var.value}"
|
|
||||||
when = "destroy"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
resource "aws_instance" "bar" {
|
|
||||||
value = "hello"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "aws_instance" "foo" {
|
|
||||||
foo = "bar"
|
|
||||||
|
|
||||||
provisioner "shell" {
|
|
||||||
command = aws_instance.bar.does_not_exist
|
|
||||||
when = "destroy"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
resource "aws_instance" "bar" {
|
|
||||||
value = "hello"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "aws_instance" "foo" {
|
|
||||||
foo = "bar"
|
|
||||||
|
|
||||||
provisioner "shell" {
|
|
||||||
command = "${aws_instance.bar.value}"
|
|
||||||
when = "destroy"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,6 +2,6 @@ resource "aws_instance" "bar" {
|
||||||
for_each = toset(["a"])
|
for_each = toset(["a"])
|
||||||
provisioner "shell" {
|
provisioner "shell" {
|
||||||
when = "destroy"
|
when = "destroy"
|
||||||
command = "echo ${each.value}"
|
command = "echo ${each.key}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue