helper/schema: documentation
This commit is contained in:
parent
fb9810ca5c
commit
0c9b65f3f4
|
@ -8,15 +8,35 @@ import (
|
||||||
"github.com/hashicorp/terraform/terraform"
|
"github.com/hashicorp/terraform/terraform"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Provider represents a Resource provider in Terraform, and properly
|
// Provider represents a resource provider in Terraform, and properly
|
||||||
// implements all of the ResourceProvider API.
|
// implements all of the ResourceProvider API.
|
||||||
//
|
//
|
||||||
// This is a friendlier API than the core Terraform ResourceProvider API,
|
// By defining a schema for the configuration of the provider, the
|
||||||
// and is recommended to be used over that.
|
// map of supporting resources, and a configuration function, the schema
|
||||||
|
// framework takes over and handles all the provider operations for you.
|
||||||
|
//
|
||||||
|
// After defining the provider structure, it is unlikely that you'll require any
|
||||||
|
// of the methods on Provider itself.
|
||||||
type Provider struct {
|
type Provider struct {
|
||||||
|
// Schema is the schema for the configuration of this provider. If this
|
||||||
|
// provider has no configuration, this can be omitted.
|
||||||
|
//
|
||||||
|
// The keys of this map are the configuration keys, and the value is
|
||||||
|
// the schema describing the value of the configuration.
|
||||||
Schema map[string]*Schema
|
Schema map[string]*Schema
|
||||||
|
|
||||||
|
// ResourcesMap is the list of available resources that this provider
|
||||||
|
// can manage, along with their Resource structure defining their
|
||||||
|
// own schemas and CRUD operations.
|
||||||
|
//
|
||||||
|
// Provider automatically handles routing operations such as Apply,
|
||||||
|
// Diff, etc. to the proper resource.
|
||||||
ResourcesMap map[string]*Resource
|
ResourcesMap map[string]*Resource
|
||||||
|
|
||||||
|
// ConfigureFunc is a function for configuring the provider. If the
|
||||||
|
// provider doesn't need to be configured, this can be omitted.
|
||||||
|
//
|
||||||
|
// See the ConfigureFunc documentation for more information.
|
||||||
ConfigureFunc ConfigureFunc
|
ConfigureFunc ConfigureFunc
|
||||||
|
|
||||||
meta interface{}
|
meta interface{}
|
||||||
|
@ -25,7 +45,9 @@ type Provider struct {
|
||||||
// ConfigureFunc is the function used to configure a Provider.
|
// ConfigureFunc is the function used to configure a Provider.
|
||||||
//
|
//
|
||||||
// The interface{} value returned by this function is stored and passed into
|
// The interface{} value returned by this function is stored and passed into
|
||||||
// the subsequent resources as the meta parameter.
|
// the subsequent resources as the meta parameter. This return value is
|
||||||
|
// usually used to pass along a configured API client, a configuration
|
||||||
|
// structure, etc.
|
||||||
type ConfigureFunc func(*ResourceData) (interface{}, error)
|
type ConfigureFunc func(*ResourceData) (interface{}, error)
|
||||||
|
|
||||||
// InternalValidate should be called to validate the structure
|
// InternalValidate should be called to validate the structure
|
||||||
|
@ -65,13 +87,12 @@ func (p *Provider) SetMeta(v interface{}) {
|
||||||
p.meta = v
|
p.meta = v
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate validates the provider configuration against the schema.
|
// Validate implementation of terraform.ResourceProvider interface.
|
||||||
func (p *Provider) Validate(c *terraform.ResourceConfig) ([]string, []error) {
|
func (p *Provider) Validate(c *terraform.ResourceConfig) ([]string, []error) {
|
||||||
return schemaMap(p.Schema).Validate(c)
|
return schemaMap(p.Schema).Validate(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValidateResource validates the resource configuration against the
|
// ValidateResource implementation of terraform.ResourceProvider interface.
|
||||||
// proper schema.
|
|
||||||
func (p *Provider) ValidateResource(
|
func (p *Provider) ValidateResource(
|
||||||
t string, c *terraform.ResourceConfig) ([]string, []error) {
|
t string, c *terraform.ResourceConfig) ([]string, []error) {
|
||||||
r, ok := p.ResourcesMap[t]
|
r, ok := p.ResourcesMap[t]
|
||||||
|
|
|
@ -7,31 +7,58 @@ import (
|
||||||
"github.com/hashicorp/terraform/terraform"
|
"github.com/hashicorp/terraform/terraform"
|
||||||
)
|
)
|
||||||
|
|
||||||
// The functions below are the CRUD function types for a Resource.
|
|
||||||
//
|
|
||||||
// The second parameter is the meta value sent to the resource when
|
|
||||||
// different operations are called.
|
|
||||||
type CreateFunc func(*ResourceData, interface{}) error
|
|
||||||
type ReadFunc func(*ResourceData, interface{}) error
|
|
||||||
type UpdateFunc func(*ResourceData, interface{}) error
|
|
||||||
type DeleteFunc func(*ResourceData, interface{}) error
|
|
||||||
|
|
||||||
// Resource represents a thing in Terraform that has a set of configurable
|
// Resource represents a thing in Terraform that has a set of configurable
|
||||||
// attributes and generally also has a lifecycle (create, read, update,
|
// attributes and a lifecycle (create, read, update, delete).
|
||||||
// delete).
|
|
||||||
//
|
//
|
||||||
// The Resource schema is an abstraction that allows provider writers to
|
// The Resource schema is an abstraction that allows provider writers to
|
||||||
// worry only about CRUD operations while off-loading validation, diff
|
// worry only about CRUD operations while off-loading validation, diff
|
||||||
// generation, etc. to this higher level library.
|
// generation, etc. to this higher level library.
|
||||||
type Resource struct {
|
type Resource struct {
|
||||||
|
// Schema is the schema for the configuration of this resource.
|
||||||
|
//
|
||||||
|
// The keys of this map are the configuration keys, and the values
|
||||||
|
// describe the schema of the configuration value.
|
||||||
|
//
|
||||||
|
// The schema is used to represent both configurable data as well
|
||||||
|
// as data that might be computed in the process of creating this
|
||||||
|
// resource.
|
||||||
Schema map[string]*Schema
|
Schema map[string]*Schema
|
||||||
|
|
||||||
|
// The functions below are the CRUD operations for this resource.
|
||||||
|
//
|
||||||
|
// The only optional operation is Update. If Update is not implemented,
|
||||||
|
// then updates will not be supported for this resource.
|
||||||
|
//
|
||||||
|
// The ResourceData parameter in the functions below are used to
|
||||||
|
// query configuration and changes for the resource as well as to set
|
||||||
|
// the ID, computed data, etc.
|
||||||
|
//
|
||||||
|
// The interface{} parameter is the result of the ConfigureFunc in
|
||||||
|
// the provider for this resource. If the provider does not define
|
||||||
|
// a ConfigureFunc, this will be nil. This parameter should be used
|
||||||
|
// to store API clients, configuration structures, etc.
|
||||||
|
//
|
||||||
|
// If any errors occur during each of the operation, an error should be
|
||||||
|
// returned. If a resource was partially updated, be careful to enable
|
||||||
|
// partial state mode for ResourceData and use it accordingly.
|
||||||
Create CreateFunc
|
Create CreateFunc
|
||||||
Read ReadFunc
|
Read ReadFunc
|
||||||
Update UpdateFunc
|
Update UpdateFunc
|
||||||
Delete DeleteFunc
|
Delete DeleteFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// See Resource documentation.
|
||||||
|
type CreateFunc func(*ResourceData, interface{}) error
|
||||||
|
|
||||||
|
// See Resource documentation.
|
||||||
|
type ReadFunc func(*ResourceData, interface{}) error
|
||||||
|
|
||||||
|
// See Resource documentation.
|
||||||
|
type UpdateFunc func(*ResourceData, interface{}) error
|
||||||
|
|
||||||
|
// See Resource documentation.
|
||||||
|
type DeleteFunc func(*ResourceData, interface{}) error
|
||||||
|
|
||||||
// Apply creates, updates, and/or deletes a resource.
|
// Apply creates, updates, and/or deletes a resource.
|
||||||
func (r *Resource) Apply(
|
func (r *Resource) Apply(
|
||||||
s *terraform.ResourceState,
|
s *terraform.ResourceState,
|
||||||
|
@ -121,6 +148,10 @@ func (r *Resource) Refresh(
|
||||||
// This should be called in a unit test for any resource to verify
|
// This should be called in a unit test for any resource to verify
|
||||||
// before release that a resource is properly configured for use with
|
// before release that a resource is properly configured for use with
|
||||||
// this library.
|
// this library.
|
||||||
|
//
|
||||||
|
// 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() error {
|
func (r *Resource) InternalValidate() error {
|
||||||
if r == nil {
|
if r == nil {
|
||||||
return errors.New("resource is nil")
|
return errors.New("resource is nil")
|
||||||
|
|
|
@ -11,6 +11,30 @@ import (
|
||||||
"github.com/mitchellh/mapstructure"
|
"github.com/mitchellh/mapstructure"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ResourceData is used to query and set the attributes of a resource.
|
||||||
|
//
|
||||||
|
// ResourceData is the primary argument received for CRUD operations on
|
||||||
|
// a resource as well as configuration of a provider. It is a powerful
|
||||||
|
// structure that can be used to not only query data, but check for changes,
|
||||||
|
// define partial state updates, etc.
|
||||||
|
//
|
||||||
|
// The most relevant methods to take a look at are Get, Set, and Partial.
|
||||||
|
type ResourceData struct {
|
||||||
|
// Settable (internally)
|
||||||
|
schema map[string]*Schema
|
||||||
|
config *terraform.ResourceConfig
|
||||||
|
state *terraform.ResourceState
|
||||||
|
diff *terraform.ResourceDiff
|
||||||
|
diffing bool
|
||||||
|
|
||||||
|
// Don't set
|
||||||
|
setMap map[string]string
|
||||||
|
newState *terraform.ResourceState
|
||||||
|
partial bool
|
||||||
|
partialMap map[string]struct{}
|
||||||
|
once sync.Once
|
||||||
|
}
|
||||||
|
|
||||||
// getSource represents the level we want to get for a value (internally).
|
// getSource represents the level we want to get for a value (internally).
|
||||||
// Any source less than or equal to the level will be loaded (whichever
|
// Any source less than or equal to the level will be loaded (whichever
|
||||||
// has a value first).
|
// has a value first).
|
||||||
|
@ -34,21 +58,6 @@ type getResult struct {
|
||||||
|
|
||||||
var getResultEmpty getResult
|
var getResultEmpty getResult
|
||||||
|
|
||||||
// ResourceData is used to query and set the attributes of a resource.
|
|
||||||
type ResourceData struct {
|
|
||||||
schema map[string]*Schema
|
|
||||||
config *terraform.ResourceConfig
|
|
||||||
state *terraform.ResourceState
|
|
||||||
diff *terraform.ResourceDiff
|
|
||||||
diffing bool
|
|
||||||
|
|
||||||
setMap map[string]string
|
|
||||||
newState *terraform.ResourceState
|
|
||||||
partial bool
|
|
||||||
partialMap map[string]struct{}
|
|
||||||
once sync.Once
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get returns the data for the given key, or nil if the key doesn't exist
|
// Get returns the data for the given key, or nil if the key doesn't exist
|
||||||
// in the schema.
|
// in the schema.
|
||||||
//
|
//
|
||||||
|
@ -56,7 +65,8 @@ type ResourceData struct {
|
||||||
// then the default value for that type will be returned. For strings, this is
|
// then the default value for that type will be returned. For strings, this is
|
||||||
// "", for numbers it is 0, etc.
|
// "", for numbers it is 0, etc.
|
||||||
//
|
//
|
||||||
// If you also want to test if something is set at all, use GetOk.
|
// If you want to test if something is set at all in the configuration,
|
||||||
|
// use GetOk.
|
||||||
func (d *ResourceData) Get(key string) interface{} {
|
func (d *ResourceData) Get(key string) interface{} {
|
||||||
v, _ := d.GetOk(key)
|
v, _ := d.GetOk(key)
|
||||||
return v
|
return v
|
||||||
|
@ -64,7 +74,10 @@ func (d *ResourceData) Get(key string) interface{} {
|
||||||
|
|
||||||
// GetChange returns the old and new value for a given key.
|
// GetChange returns the old and new value for a given key.
|
||||||
//
|
//
|
||||||
// If there is no change, then old and new will simply be the same.
|
// HasChange should be used to check if a change exists. It is possible
|
||||||
|
// that both the old and new value are the same if the old value was not
|
||||||
|
// set and the new value is. This is common, for example, for boolean
|
||||||
|
// fields which have a zero value of false.
|
||||||
func (d *ResourceData) GetChange(key string) (interface{}, interface{}) {
|
func (d *ResourceData) GetChange(key string) (interface{}, interface{}) {
|
||||||
o, n := d.getChange(key, getSourceConfig, getSourceDiff)
|
o, n := d.getChange(key, getSourceConfig, getSourceDiff)
|
||||||
return o.Value, n.Value
|
return o.Value, n.Value
|
||||||
|
@ -73,6 +86,9 @@ func (d *ResourceData) GetChange(key string) (interface{}, interface{}) {
|
||||||
// GetOk returns the data for the given key and whether or not the key
|
// GetOk returns the data for the given key and whether or not the key
|
||||||
// existed or not in the configuration. The second boolean result will also
|
// existed or not in the configuration. The second boolean result will also
|
||||||
// be false if a key is given that isn't in the schema at all.
|
// be false if a key is given that isn't in the schema at all.
|
||||||
|
//
|
||||||
|
// The first result will not necessarilly be nil if the value doesn't exist.
|
||||||
|
// The second result should be checked to determine this information.
|
||||||
func (d *ResourceData) GetOk(key string) (interface{}, bool) {
|
func (d *ResourceData) GetOk(key string) (interface{}, bool) {
|
||||||
r := d.getRaw(key, getSourceSet)
|
r := d.getRaw(key, getSourceSet)
|
||||||
return r.Value, r.Exists
|
return r.Value, r.Exists
|
||||||
|
@ -98,6 +114,9 @@ func (d *ResourceData) HasChange(key string) bool {
|
||||||
// When partial state mode is enabled, then only key prefixes specified
|
// When partial state mode is enabled, then only key prefixes specified
|
||||||
// by SetPartial will be in the final state. This allows providers to return
|
// by SetPartial will be in the final state. This allows providers to return
|
||||||
// partial states for partially applied resources (when errors occur).
|
// partial states for partially applied resources (when errors occur).
|
||||||
|
//
|
||||||
|
// When partial state mode is toggled, the map of enabled partial states
|
||||||
|
// (by SetPartial) is reset.
|
||||||
func (d *ResourceData) Partial(on bool) {
|
func (d *ResourceData) Partial(on bool) {
|
||||||
d.partial = on
|
d.partial = on
|
||||||
if on {
|
if on {
|
||||||
|
|
|
@ -1,3 +1,14 @@
|
||||||
|
// schema is a high-level framework for easily writing new providers
|
||||||
|
// for Terraform. Usage of schema is recommended over attempting to write
|
||||||
|
// to the low-level plugin interfaces manually.
|
||||||
|
//
|
||||||
|
// schema breaks down provider creation into simple CRUD operations for
|
||||||
|
// resources. The logic of diffing, destroying before creating, updating
|
||||||
|
// or creating, etc. is all handled by the framework. The plugin author
|
||||||
|
// only needs to implement a configuration schema and the CRUD operations and
|
||||||
|
// everything else is meant to just work.
|
||||||
|
//
|
||||||
|
// A good starting point is to view the Provider structure.
|
||||||
package schema
|
package schema
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -24,8 +35,22 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
// Schema is used to describe the structure of a value.
|
// Schema is used to describe the structure of a value.
|
||||||
|
//
|
||||||
|
// Read the documentation of the struct elements for important details.
|
||||||
type Schema struct {
|
type Schema struct {
|
||||||
// Type is the type of the value and must be one of the ValueType values.
|
// Type is the type of the value and must be one of the ValueType values.
|
||||||
|
//
|
||||||
|
// This type not only determines what type is expected/valid in configuring
|
||||||
|
// this value, but also what type is returned when ResourceData.Get is
|
||||||
|
// called. The types returned by Get are:
|
||||||
|
//
|
||||||
|
// TypeBool - bool
|
||||||
|
// TypeInt - int
|
||||||
|
// TypeString - string
|
||||||
|
// TypeList - []interface{}
|
||||||
|
// TypeMap - map[string]interface{}
|
||||||
|
// TypeSet - *schema.Set
|
||||||
|
//
|
||||||
Type ValueType
|
Type ValueType
|
||||||
|
|
||||||
// If one of these is set, then this item can come from the configuration.
|
// If one of these is set, then this item can come from the configuration.
|
||||||
|
@ -70,6 +95,8 @@ type Schema struct {
|
||||||
// ComputedWhen is a set of queries on the configuration. Whenever any
|
// ComputedWhen is a set of queries on the configuration. Whenever any
|
||||||
// of these things is changed, it will require a recompute (this requires
|
// of these things is changed, it will require a recompute (this requires
|
||||||
// that Computed is set to true).
|
// that Computed is set to true).
|
||||||
|
//
|
||||||
|
// NOTE: This currently does not work.
|
||||||
ComputedWhen []string
|
ComputedWhen []string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue