helper/schema: initial work
This commit is contained in:
parent
3e3be5e2a3
commit
01b6b5f48e
|
@ -0,0 +1,56 @@
|
|||
package schema
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// The functions below are the CRUD function types for a Resource.
|
||||
type CreateFunc func(*ResourceData) error
|
||||
type ReadFunc func(*ResourceData) error
|
||||
type UpdateFunc func(*ResourceData) error
|
||||
type DeleteFunc func(*ResourceData) error
|
||||
|
||||
// Resource represents a thing in Terraform that has a set of configurable
|
||||
// attributes and generally also has a lifecycle (create, read, update,
|
||||
// delete).
|
||||
//
|
||||
// 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.
|
||||
type Resource struct {
|
||||
Schema map[string]*Schema
|
||||
|
||||
Create CreateFunc
|
||||
Read ReadFunc
|
||||
Update UpdateFunc
|
||||
Delete DeleteFunc
|
||||
}
|
||||
|
||||
// InternalValidate should be called to validate the structure
|
||||
// of the resource.
|
||||
//
|
||||
// This should be called in a unit test for any resource to verify
|
||||
// before release that a resource is properly configured for use with
|
||||
// this library.
|
||||
func (r *Resource) InternalValidate() error {
|
||||
if r == nil {
|
||||
return errors.New("resource is nil")
|
||||
}
|
||||
|
||||
for k, v := range r.Schema {
|
||||
if v.Type == TypeInvalid {
|
||||
return fmt.Errorf("%s: Type must be specified", k)
|
||||
}
|
||||
|
||||
if v.Optional && v.Required {
|
||||
return fmt.Errorf("%s: Optional or Required must be set, not both", k)
|
||||
}
|
||||
|
||||
if v.Required && v.Computed {
|
||||
return fmt.Errorf("%s: Cannot be both Required and Computed", k)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
package schema
|
||||
|
||||
// ResourceData is used to query and set the attributes of a resource.
|
||||
type ResourceData struct{}
|
|
@ -0,0 +1,77 @@
|
|||
package schema
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestResourceInternalValidate(t *testing.T) {
|
||||
cases := []struct {
|
||||
In *Resource
|
||||
Err bool
|
||||
}{
|
||||
{
|
||||
nil,
|
||||
true,
|
||||
},
|
||||
|
||||
// No optional and no required
|
||||
{
|
||||
&Resource{
|
||||
Schema: map[string]*Schema{
|
||||
"foo": &Schema{
|
||||
Type: TypeInt,
|
||||
Optional: true,
|
||||
Required: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
true,
|
||||
},
|
||||
|
||||
// Missing Type
|
||||
{
|
||||
&Resource{
|
||||
Schema: map[string]*Schema{
|
||||
"foo": &Schema{
|
||||
Required: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
true,
|
||||
},
|
||||
|
||||
// Required but computed
|
||||
{
|
||||
&Resource{
|
||||
Schema: map[string]*Schema{
|
||||
"foo": &Schema{
|
||||
Type: TypeInt,
|
||||
Required: true,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
true,
|
||||
},
|
||||
|
||||
// Looks good
|
||||
{
|
||||
&Resource{
|
||||
Schema: map[string]*Schema{
|
||||
"foo": &Schema{
|
||||
Type: TypeString,
|
||||
Required: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
for i, tc := range cases {
|
||||
err := tc.In.InternalValidate()
|
||||
if (err != nil) != tc.Err {
|
||||
t.Fatalf("%d: bad: %s", i, err)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package schema
|
||||
|
||||
// ValueType is an enum of the type that can be represented by a schema.
|
||||
type ValueType int
|
||||
|
||||
const (
|
||||
TypeInvalid ValueType = iota
|
||||
TypeBoolean
|
||||
TypeInt
|
||||
TypeString
|
||||
TypeList
|
||||
)
|
||||
|
||||
// Schema is used to describe the structure of a value.
|
||||
type Schema struct {
|
||||
// Type is the type of the value and must be one of the ValueType values.
|
||||
Type ValueType
|
||||
|
||||
// If one of these is set, then this item can come from the configuration.
|
||||
// Both cannot be set. If Optional is set, the value is optional. If
|
||||
// Required is set, the value is required.
|
||||
Optional bool
|
||||
Required bool
|
||||
|
||||
// The fields below relate to diffs: if Computed is true, then the
|
||||
// result of this value is computed (unless specified by config).
|
||||
// If ForceNew is true
|
||||
Computed bool
|
||||
ForceNew bool
|
||||
|
||||
// Elem must be either a *Schema or a *Resource only if the Type is
|
||||
// TypeList, and represents what the element type is. If it is *Schema,
|
||||
// the element type is just a simple value. If it is *Resource, the
|
||||
// element type is a complex structure, potentially with its own lifecycle.
|
||||
Elem interface{}
|
||||
}
|
Loading…
Reference in New Issue