insert resource timeouts into the config schema

Resource timeouts were a separate config block, but did not exist in the
resource schema. Insert any defined timeouts when generating the
configshema.Block so that the fields can be accepted and validated by
core.
This commit is contained in:
James Bardin 2018-10-29 16:11:19 -04:00
parent ab88f8ca0f
commit 6dad121e70
4 changed files with 93 additions and 4 deletions

View File

@ -463,7 +463,7 @@ func (s *GRPCProviderServer) PlanResourceChange(_ context.Context, req *proto.Pl
} }
priorState.Meta = priorPrivate priorState.Meta = priorPrivate
// turn the propsed state into a legacy configuration // turn the proposed state into a legacy configuration
config := terraform.NewResourceConfigShimmed(proposedNewStateVal, block) config := terraform.NewResourceConfigShimmed(proposedNewStateVal, block)
diff, err := s.provider.SimpleDiff(info, priorState, config) diff, err := s.provider.SimpleDiff(info, priorState, config)

View File

@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"strings" "strings"
"testing" "testing"
"time"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts" "github.com/google/go-cmp/cmp/cmpopts"
@ -388,8 +389,8 @@ func TestApplyResourceChange(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
// A propsed state with only the ID unknown will produce a nil diff, and // A proposed state with only the ID unknown will produce a nil diff, and
// should return the propsed state value. // should return the proposed state value.
plannedVal, err := schema.CoerceValue(cty.ObjectVal(map[string]cty.Value{ plannedVal, err := schema.CoerceValue(cty.ObjectVal(map[string]cty.Value{
"id": cty.UnknownVal(cty.String), "id": cty.UnknownVal(cty.String),
})) }))
@ -595,3 +596,44 @@ func TestPrepareProviderConfig(t *testing.T) {
}) })
} }
} }
func TestGetSchemaTimeouts(t *testing.T) {
r := &schema.Resource{
SchemaVersion: 4,
Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(time.Second),
Read: schema.DefaultTimeout(2 * time.Second),
Update: schema.DefaultTimeout(3 * time.Second),
Default: schema.DefaultTimeout(10 * time.Second),
},
Schema: map[string]*schema.Schema{
"foo": {
Type: schema.TypeInt,
Optional: true,
},
},
}
// verify that the timeouts appear in the schema as defined
block := r.CoreConfigSchema()
timeoutsBlock := block.BlockTypes["timeouts"]
if timeoutsBlock == nil {
t.Fatal("missing timeouts in schema")
}
if timeoutsBlock.Attributes["create"] == nil {
t.Fatal("missing create timeout in schema")
}
if timeoutsBlock.Attributes["read"] == nil {
t.Fatal("missing read timeout in schema")
}
if timeoutsBlock.Attributes["update"] == nil {
t.Fatal("missing update timeout in schema")
}
if d := timeoutsBlock.Attributes["delete"]; d != nil {
t.Fatalf("unexpected delete timeout in schema: %#v", d)
}
if timeoutsBlock.Attributes["default"] == nil {
t.Fatal("missing default timeout in schema")
}
}

View File

@ -172,6 +172,53 @@ func (r *Resource) CoreConfigSchema() *configschema.Block {
} }
} }
// insert configured timeout values into the schema
if r.Timeouts != nil {
timeouts := configschema.Block{
Attributes: map[string]*configschema.Attribute{},
}
if r.Timeouts.Create != nil {
timeouts.Attributes["create"] = &configschema.Attribute{
Type: cty.String,
Optional: true,
}
}
if r.Timeouts.Read != nil {
timeouts.Attributes["read"] = &configschema.Attribute{
Type: cty.String,
Optional: true,
}
}
if r.Timeouts.Update != nil {
timeouts.Attributes["update"] = &configschema.Attribute{
Type: cty.String,
Optional: true,
}
}
if r.Timeouts.Delete != nil {
timeouts.Attributes["delete"] = &configschema.Attribute{
Type: cty.String,
Optional: true,
}
}
if r.Timeouts.Default != nil {
timeouts.Attributes["default"] = &configschema.Attribute{
Type: cty.String,
Optional: true,
}
}
block.BlockTypes["timeouts"] = &configschema.NestedBlock{
Nesting: configschema.NestingSingle,
Block: timeouts,
}
}
return block return block
} }

View File

@ -276,7 +276,7 @@ func newResourceConfigShimmedComputedKeys(obj cty.Value, schema *configschema.Bl
} }
blockVal := obj.GetAttr(typeName) blockVal := obj.GetAttr(typeName)
if !blockVal.IsKnown() || blockVal.IsNull() { if blockVal.IsNull() || !blockVal.IsKnown() {
continue continue
} }