Merge pull request #20295 from hashicorp/jbardin/apply-error
process state even after provider.Apply errors
This commit is contained in:
commit
d871ce63fc
|
@ -1,6 +1,7 @@
|
||||||
package test
|
package test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/helper/schema"
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
@ -123,6 +124,11 @@ func testResource() *schema.Resource {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"apply_error": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Description: "return and error during apply",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -130,6 +136,11 @@ func testResource() *schema.Resource {
|
||||||
func testResourceCreate(d *schema.ResourceData, meta interface{}) error {
|
func testResourceCreate(d *schema.ResourceData, meta interface{}) error {
|
||||||
d.SetId("testId")
|
d.SetId("testId")
|
||||||
|
|
||||||
|
errMsg, _ := d.Get("apply_error").(string)
|
||||||
|
if errMsg != "" {
|
||||||
|
return errors.New(errMsg)
|
||||||
|
}
|
||||||
|
|
||||||
// Required must make it through to Create
|
// Required must make it through to Create
|
||||||
if _, ok := d.GetOk("required"); !ok {
|
if _, ok := d.GetOk("required"); !ok {
|
||||||
return fmt.Errorf("Missing attribute 'required', but it's required!")
|
return fmt.Errorf("Missing attribute 'required', but it's required!")
|
||||||
|
@ -156,6 +167,10 @@ func testResourceRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func testResourceUpdate(d *schema.ResourceData, meta interface{}) error {
|
func testResourceUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
errMsg, _ := d.Get("apply_error").(string)
|
||||||
|
if errMsg != "" {
|
||||||
|
return errors.New(errMsg)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ package test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
@ -624,3 +625,55 @@ resource "test_resource" "foo" {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestResource_updateError(t *testing.T) {
|
||||||
|
resource.UnitTest(t, resource.TestCase{
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckResourceDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: strings.TrimSpace(`
|
||||||
|
resource "test_resource" "foo" {
|
||||||
|
required = "first"
|
||||||
|
required_map = {
|
||||||
|
a = "a"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`),
|
||||||
|
},
|
||||||
|
resource.TestStep{
|
||||||
|
Config: strings.TrimSpace(`
|
||||||
|
resource "test_resource" "foo" {
|
||||||
|
required = "second"
|
||||||
|
required_map = {
|
||||||
|
a = "a"
|
||||||
|
}
|
||||||
|
apply_error = "update_error"
|
||||||
|
}
|
||||||
|
`),
|
||||||
|
ExpectError: regexp.MustCompile("update_error"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestResource_applyError(t *testing.T) {
|
||||||
|
resource.UnitTest(t, resource.TestCase{
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckResourceDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: strings.TrimSpace(`
|
||||||
|
resource "test_resource" "foo" {
|
||||||
|
required = "second"
|
||||||
|
required_map = {
|
||||||
|
a = "a"
|
||||||
|
}
|
||||||
|
apply_error = "apply_error"
|
||||||
|
}
|
||||||
|
`),
|
||||||
|
ExpectError: regexp.MustCompile("apply_error"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -656,7 +656,10 @@ func (s *GRPCProviderServer) PlanResourceChange(_ context.Context, req *proto.Pl
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *GRPCProviderServer) ApplyResourceChange(_ context.Context, req *proto.ApplyResourceChange_Request) (*proto.ApplyResourceChange_Response, error) {
|
func (s *GRPCProviderServer) ApplyResourceChange(_ context.Context, req *proto.ApplyResourceChange_Request) (*proto.ApplyResourceChange_Response, error) {
|
||||||
resp := &proto.ApplyResourceChange_Response{}
|
resp := &proto.ApplyResourceChange_Response{
|
||||||
|
// Start with the existing state as a fallback
|
||||||
|
NewState: req.PriorState,
|
||||||
|
}
|
||||||
|
|
||||||
res := s.provider.ResourcesMap[req.TypeName]
|
res := s.provider.ResourcesMap[req.TypeName]
|
||||||
block := res.CoreConfigSchema()
|
block := res.CoreConfigSchema()
|
||||||
|
@ -753,15 +756,17 @@ func (s *GRPCProviderServer) ApplyResourceChange(_ context.Context, req *proto.A
|
||||||
}
|
}
|
||||||
|
|
||||||
newInstanceState, err := s.provider.Apply(info, priorState, diff)
|
newInstanceState, err := s.provider.Apply(info, priorState, diff)
|
||||||
|
// we record the error here, but continue processing any returned state.
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err)
|
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err)
|
||||||
return resp, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
newStateVal := cty.NullVal(block.ImpliedType())
|
newStateVal := cty.NullVal(block.ImpliedType())
|
||||||
|
|
||||||
// always return a nul value for destroy
|
// Always return a null value for destroy.
|
||||||
if newInstanceState == nil || destroy {
|
// While this is usually indicated by a nil state, check for missing ID or
|
||||||
|
// attributes in the case of a provider failure.
|
||||||
|
if destroy || newInstanceState == nil || newInstanceState.Attributes == nil || newInstanceState.ID == "" {
|
||||||
newStateMP, err := msgpack.Marshal(newStateVal, block.ImpliedType())
|
newStateMP, err := msgpack.Marshal(newStateVal, block.ImpliedType())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err)
|
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err)
|
||||||
|
|
Loading…
Reference in New Issue