helper/schema: Resource can be writable or not
In the "schema" layer a Resource is just any "thing" that has a schema and supports some or all of the CRUD operations. Data sources introduce a new use of Resource to represent read-only resources, which require some different InternalValidate logic.
This commit is contained in:
parent
0e0e3d73af
commit
6a468dcd83
|
@ -75,21 +75,15 @@ func (p *Provider) InternalValidate() error {
|
|||
}
|
||||
|
||||
for k, r := range p.ResourcesMap {
|
||||
if err := r.InternalValidate(nil); err != nil {
|
||||
if err := r.InternalValidate(nil, true); err != nil {
|
||||
return fmt.Errorf("resource %s: %s", k, err)
|
||||
}
|
||||
}
|
||||
|
||||
for k, r := range p.DataSourcesMap {
|
||||
if err := r.InternalValidate(nil); err != nil {
|
||||
if err := r.InternalValidate(nil, false); err != nil {
|
||||
return fmt.Errorf("data source %s: %s", k, err)
|
||||
}
|
||||
|
||||
if r.Create != nil || r.Update != nil || r.Delete != nil {
|
||||
return fmt.Errorf(
|
||||
"data source %s: must not have Create, Update or Delete", k,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -14,6 +14,10 @@ import (
|
|||
// The Resource schema is an abstraction that allows provider writers to
|
||||
// worry only about CRUD operations while off-loading validation, diff
|
||||
// generation, etc. to this higher level library.
|
||||
//
|
||||
// In spite of the name, this struct is not used only for terraform resources,
|
||||
// but also for data sources. In the case of data sources, the Create,
|
||||
// Update and Delete functions must not be provided.
|
||||
type Resource struct {
|
||||
// Schema is the schema for the configuration of this resource.
|
||||
//
|
||||
|
@ -260,13 +264,20 @@ func (r *Resource) Refresh(
|
|||
// Provider.InternalValidate() will automatically call this for all of
|
||||
// the resources it manages, so you don't need to call this manually if it
|
||||
// is part of a Provider.
|
||||
func (r *Resource) InternalValidate(topSchemaMap schemaMap) error {
|
||||
func (r *Resource) InternalValidate(topSchemaMap schemaMap, writable bool) error {
|
||||
if r == nil {
|
||||
return errors.New("resource is nil")
|
||||
}
|
||||
|
||||
if !writable {
|
||||
if r.Create != nil || r.Update != nil || r.Delete != nil {
|
||||
return fmt.Errorf("must not implement Create, Update or Delete")
|
||||
}
|
||||
}
|
||||
|
||||
tsm := topSchemaMap
|
||||
|
||||
if r.isTopLevel() {
|
||||
if r.isTopLevel() && writable {
|
||||
// All non-Computed attributes must be ForceNew if Update is not defined
|
||||
if r.Update == nil {
|
||||
nonForceNewAttrs := make([]string, 0)
|
||||
|
|
|
@ -395,12 +395,14 @@ func TestResourceApply_isNewResource(t *testing.T) {
|
|||
|
||||
func TestResourceInternalValidate(t *testing.T) {
|
||||
cases := []struct {
|
||||
In *Resource
|
||||
Err bool
|
||||
In *Resource
|
||||
Writable bool
|
||||
Err bool
|
||||
}{
|
||||
{
|
||||
nil,
|
||||
true,
|
||||
true,
|
||||
},
|
||||
|
||||
// No optional and no required
|
||||
|
@ -415,6 +417,7 @@ func TestResourceInternalValidate(t *testing.T) {
|
|||
},
|
||||
},
|
||||
true,
|
||||
true,
|
||||
},
|
||||
|
||||
// Update undefined for non-ForceNew field
|
||||
|
@ -429,6 +432,7 @@ func TestResourceInternalValidate(t *testing.T) {
|
|||
},
|
||||
},
|
||||
true,
|
||||
true,
|
||||
},
|
||||
|
||||
// Update defined for ForceNew field
|
||||
|
@ -445,11 +449,41 @@ func TestResourceInternalValidate(t *testing.T) {
|
|||
},
|
||||
},
|
||||
true,
|
||||
true,
|
||||
},
|
||||
|
||||
// non-writable doesn't need Update, Create or Delete
|
||||
{
|
||||
&Resource{
|
||||
Schema: map[string]*Schema{
|
||||
"goo": &Schema{
|
||||
Type: TypeInt,
|
||||
Optional: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
false,
|
||||
false,
|
||||
},
|
||||
|
||||
// non-writable *must not* have Create
|
||||
{
|
||||
&Resource{
|
||||
Create: func(d *ResourceData, meta interface{}) error { return nil },
|
||||
Schema: map[string]*Schema{
|
||||
"goo": &Schema{
|
||||
Type: TypeInt,
|
||||
Optional: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
false,
|
||||
true,
|
||||
},
|
||||
}
|
||||
|
||||
for i, tc := range cases {
|
||||
err := tc.In.InternalValidate(schemaMap{})
|
||||
err := tc.In.InternalValidate(schemaMap{}, tc.Writable)
|
||||
if err != nil != tc.Err {
|
||||
t.Fatalf("%d: bad: %s", i, err)
|
||||
}
|
||||
|
|
|
@ -553,7 +553,7 @@ func (m schemaMap) InternalValidate(topSchemaMap schemaMap) error {
|
|||
|
||||
switch t := v.Elem.(type) {
|
||||
case *Resource:
|
||||
if err := t.InternalValidate(topSchemaMap); err != nil {
|
||||
if err := t.InternalValidate(topSchemaMap, true); err != nil {
|
||||
return err
|
||||
}
|
||||
case *Schema:
|
||||
|
|
Loading…
Reference in New Issue