opentofu/helper/schema/backend.go
Chris Marchesi 8af9610b87 helper/schema: Hook CustomizeDiffFunc into diff logic
It's alive! CustomizeDiff logic now has been inserted into the diff
process. The test_resource_with_custom_diff resource provides some basic
testing and a reference implementation.

There should now be plenty of test coverage for this feature via the
tests added for ResourceDiff, and the basic test added to the
schemaMap.Diff test, and the test resource, but more can be added to
test any specific case that comes up otherwise.
2017-11-01 14:25:32 -07:00

95 lines
2.4 KiB
Go

package schema
import (
"context"
"github.com/hashicorp/terraform/terraform"
)
// Backend represents a partial backend.Backend implementation and simplifies
// the creation of configuration loading and validation.
//
// Unlike other schema structs such as Provider, this struct is meant to be
// embedded within your actual implementation. It provides implementations
// only for Input and Configure and gives you a method for accessing the
// configuration in the form of a ResourceData that you're expected to call
// from the other implementation funcs.
type Backend struct {
// Schema is the schema for the configuration of this backend. If this
// Backend has no configuration this can be omitted.
Schema map[string]*Schema
// ConfigureFunc is called to configure the backend. Use the
// FromContext* methods to extract information from the context.
// This can be nil, in which case nothing will be called but the
// config will still be stored.
ConfigureFunc func(context.Context) error
config *ResourceData
}
var (
backendConfigKey = contextKey("backend config")
)
// FromContextBackendConfig extracts a ResourceData with the configuration
// from the context. This should only be called by Backend functions.
func FromContextBackendConfig(ctx context.Context) *ResourceData {
return ctx.Value(backendConfigKey).(*ResourceData)
}
func (b *Backend) Input(
input terraform.UIInput,
c *terraform.ResourceConfig) (*terraform.ResourceConfig, error) {
if b == nil {
return c, nil
}
return schemaMap(b.Schema).Input(input, c)
}
func (b *Backend) Validate(c *terraform.ResourceConfig) ([]string, []error) {
if b == nil {
return nil, nil
}
return schemaMap(b.Schema).Validate(c)
}
func (b *Backend) Configure(c *terraform.ResourceConfig) error {
if b == nil {
return nil
}
sm := schemaMap(b.Schema)
// Get a ResourceData for this configuration. To do this, we actually
// generate an intermediary "diff" although that is never exposed.
diff, err := sm.Diff(nil, c, nil, nil)
if err != nil {
return err
}
data, err := sm.Data(nil, diff)
if err != nil {
return err
}
b.config = data
if b.ConfigureFunc != nil {
err = b.ConfigureFunc(context.WithValue(
context.Background(), backendConfigKey, data))
if err != nil {
return err
}
}
return nil
}
// Config returns the configuration. This is available after Configure is
// called.
func (b *Backend) Config() *ResourceData {
return b.config
}