ResourceProvisioner to provisioners.Interface

Replacing the core types, without touching tests yet.
This commit is contained in:
James Bardin 2018-08-17 12:42:07 -04:00 committed by Martin Atkins
parent ad7eee7ba4
commit 08a8834882
11 changed files with 45 additions and 48 deletions

View File

@ -16,6 +16,7 @@ import (
"github.com/hashicorp/terraform/lang" "github.com/hashicorp/terraform/lang"
"github.com/hashicorp/terraform/plans" "github.com/hashicorp/terraform/plans"
"github.com/hashicorp/terraform/providers" "github.com/hashicorp/terraform/providers"
"github.com/hashicorp/terraform/provisioners"
"github.com/hashicorp/terraform/states" "github.com/hashicorp/terraform/states"
"github.com/hashicorp/terraform/tfdiags" "github.com/hashicorp/terraform/tfdiags"
) )
@ -65,7 +66,7 @@ type ContextOpts struct {
Hooks []Hook Hooks []Hook
Parallelism int Parallelism int
ProviderResolver providers.Resolver ProviderResolver providers.Resolver
Provisioners map[string]ResourceProvisionerFactory Provisioners map[string]ProvisionerFactory
// If non-nil, will apply as additional constraints on the provider // If non-nil, will apply as additional constraints on the provider
// plugins that will be requested from the provider resolver. // plugins that will be requested from the provider resolver.
@ -775,7 +776,7 @@ func (c *Context) watchStop(walker *ContextGraphWalker) (chan struct{}, <-chan s
{ {
// Call stop on all the provisioners // Call stop on all the provisioners
walker.provisionerLock.Lock() walker.provisionerLock.Lock()
ps := make([]ResourceProvisioner, 0, len(walker.provisionerCache)) ps := make([]provisioners.Interface, 0, len(walker.provisionerCache))
for _, p := range walker.provisionerCache { for _, p := range walker.provisionerCache {
ps = append(ps, p) ps = append(ps, p)
} }

View File

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"github.com/hashicorp/terraform/providers" "github.com/hashicorp/terraform/providers"
"github.com/hashicorp/terraform/provisioners"
) )
// contextComponentFactory is the interface that Context uses // contextComponentFactory is the interface that Context uses
@ -20,14 +21,14 @@ type contextComponentFactory interface {
// ResourceProvisioner creates a new ResourceProvisioner with the // ResourceProvisioner creates a new ResourceProvisioner with the
// given type. The "uid" is a unique identifier for this provisioner // given type. The "uid" is a unique identifier for this provisioner
// being initialized that can be used for internal tracking. // being initialized that can be used for internal tracking.
ResourceProvisioner(typ, uid string) (ResourceProvisioner, error) ResourceProvisioner(typ, uid string) (provisioners.Interface, error)
ResourceProvisioners() []string ResourceProvisioners() []string
} }
// basicComponentFactory just calls a factory from a map directly. // basicComponentFactory just calls a factory from a map directly.
type basicComponentFactory struct { type basicComponentFactory struct {
providers map[string]providers.Factory providers map[string]providers.Factory
provisioners map[string]ResourceProvisionerFactory provisioners map[string]ProvisionerFactory
} }
func (c *basicComponentFactory) ResourceProviders() []string { func (c *basicComponentFactory) ResourceProviders() []string {
@ -57,7 +58,7 @@ func (c *basicComponentFactory) ResourceProvider(typ, uid string) (providers.Int
return f() return f()
} }
func (c *basicComponentFactory) ResourceProvisioner(typ, uid string) (ResourceProvisioner, error) { func (c *basicComponentFactory) ResourceProvisioner(typ, uid string) (provisioners.Interface, error) {
f, ok := c.provisioners[typ] f, ok := c.provisioners[typ]
if !ok { if !ok {
return nil, fmt.Errorf("unknown provisioner %q", typ) return nil, fmt.Errorf("unknown provisioner %q", typ)

View File

@ -7,6 +7,7 @@ import (
"github.com/hashicorp/terraform/lang" "github.com/hashicorp/terraform/lang"
"github.com/hashicorp/terraform/plans" "github.com/hashicorp/terraform/plans"
"github.com/hashicorp/terraform/providers" "github.com/hashicorp/terraform/providers"
"github.com/hashicorp/terraform/provisioners"
"github.com/hashicorp/terraform/states" "github.com/hashicorp/terraform/states"
"github.com/hashicorp/terraform/tfdiags" "github.com/hashicorp/terraform/tfdiags"
"github.com/zclconf/go-cty/cty" "github.com/zclconf/go-cty/cty"
@ -68,11 +69,11 @@ type EvalContext interface {
// returns the implementation of the resource provisioner or an error. // returns the implementation of the resource provisioner or an error.
// //
// It is an error to initialize the same provisioner more than once. // It is an error to initialize the same provisioner more than once.
InitProvisioner(string) (ResourceProvisioner, error) InitProvisioner(string) (provisioners.Interface, error)
// Provisioner gets the provisioner instance with the given name (already // Provisioner gets the provisioner instance with the given name (already
// initialized) or returns nil if the provisioner isn't initialized. // initialized) or returns nil if the provisioner isn't initialized.
Provisioner(string) ResourceProvisioner Provisioner(string) provisioners.Interface
// ProvisionerSchema retrieves the main configuration schema for a // ProvisionerSchema retrieves the main configuration schema for a
// particular provisioner, which must have already been initialized with // particular provisioner, which must have already been initialized with

View File

@ -8,6 +8,7 @@ import (
"github.com/hashicorp/terraform/plans" "github.com/hashicorp/terraform/plans"
"github.com/hashicorp/terraform/providers" "github.com/hashicorp/terraform/providers"
"github.com/hashicorp/terraform/provisioners"
"github.com/hashicorp/terraform/version" "github.com/hashicorp/terraform/version"
"github.com/hashicorp/terraform/states" "github.com/hashicorp/terraform/states"
@ -58,7 +59,7 @@ type BuiltinEvalContext struct {
ProviderCache map[string]providers.Interface ProviderCache map[string]providers.Interface
ProviderInputConfig map[string]map[string]cty.Value ProviderInputConfig map[string]map[string]cty.Value
ProviderLock *sync.Mutex ProviderLock *sync.Mutex
ProvisionerCache map[string]ResourceProvisioner ProvisionerCache map[string]provisioners.Interface
ProvisionerLock *sync.Mutex ProvisionerLock *sync.Mutex
ChangesValue *plans.ChangesSync ChangesValue *plans.ChangesSync
StateValue *states.SyncState StateValue *states.SyncState
@ -211,7 +212,7 @@ func (ctx *BuiltinEvalContext) SetProviderInput(pc addrs.ProviderConfig, c map[s
ctx.ProviderLock.Unlock() ctx.ProviderLock.Unlock()
} }
func (ctx *BuiltinEvalContext) InitProvisioner(n string) (ResourceProvisioner, error) { func (ctx *BuiltinEvalContext) InitProvisioner(n string) (provisioners.Interface, error) {
ctx.once.Do(ctx.init) ctx.once.Do(ctx.init)
// If we already initialized, it is an error // If we already initialized, it is an error
@ -236,7 +237,7 @@ func (ctx *BuiltinEvalContext) InitProvisioner(n string) (ResourceProvisioner, e
return p, nil return p, nil
} }
func (ctx *BuiltinEvalContext) Provisioner(n string) ResourceProvisioner { func (ctx *BuiltinEvalContext) Provisioner(n string) provisioners.Interface {
ctx.once.Do(ctx.init) ctx.once.Do(ctx.init)
ctx.ProvisionerLock.Lock() ctx.ProvisionerLock.Lock()
@ -260,13 +261,9 @@ func (ctx *BuiltinEvalContext) CloseProvisioner(n string) error {
key := PathObjectCacheKey(ctx.Path(), n) key := PathObjectCacheKey(ctx.Path(), n)
var prov interface{} prov := ctx.ProvisionerCache[key]
prov = ctx.ProvisionerCache[key]
if prov != nil { if prov != nil {
if p, ok := prov.(ResourceProvisionerCloser); ok { return prov.Close()
delete(ctx.ProvisionerCache, key)
return p.Close()
}
} }
return nil return nil

View File

@ -12,6 +12,7 @@ import (
"github.com/hashicorp/terraform/lang" "github.com/hashicorp/terraform/lang"
"github.com/hashicorp/terraform/plans" "github.com/hashicorp/terraform/plans"
"github.com/hashicorp/terraform/providers" "github.com/hashicorp/terraform/providers"
"github.com/hashicorp/terraform/provisioners"
"github.com/hashicorp/terraform/states" "github.com/hashicorp/terraform/states"
"github.com/hashicorp/terraform/tfdiags" "github.com/hashicorp/terraform/tfdiags"
) )
@ -62,12 +63,12 @@ type MockEvalContext struct {
InitProvisionerCalled bool InitProvisionerCalled bool
InitProvisionerName string InitProvisionerName string
InitProvisionerProvisioner ResourceProvisioner InitProvisionerProvisioner provisioners.Interface
InitProvisionerError error InitProvisionerError error
ProvisionerCalled bool ProvisionerCalled bool
ProvisionerName string ProvisionerName string
ProvisionerProvisioner ResourceProvisioner ProvisionerProvisioner provisioners.Interface
ProvisionerSchemaCalled bool ProvisionerSchemaCalled bool
ProvisionerSchemaName string ProvisionerSchemaName string
@ -75,7 +76,7 @@ type MockEvalContext struct {
CloseProvisionerCalled bool CloseProvisionerCalled bool
CloseProvisionerName string CloseProvisionerName string
CloseProvisionerProvisioner ResourceProvisioner CloseProvisionerProvisioner provisioners.Interface
EvaluateBlockCalled bool EvaluateBlockCalled bool
EvaluateBlockBody hcl.Body EvaluateBlockBody hcl.Body
@ -203,13 +204,13 @@ func (c *MockEvalContext) SetProviderInput(addr addrs.ProviderConfig, vals map[s
c.SetProviderInputValues = vals c.SetProviderInputValues = vals
} }
func (c *MockEvalContext) InitProvisioner(n string) (ResourceProvisioner, error) { func (c *MockEvalContext) InitProvisioner(n string) (provisioners.Interface, error) {
c.InitProvisionerCalled = true c.InitProvisionerCalled = true
c.InitProvisionerName = n c.InitProvisionerName = n
return c.InitProvisionerProvisioner, c.InitProvisionerError return c.InitProvisionerProvisioner, c.InitProvisionerError
} }
func (c *MockEvalContext) Provisioner(n string) ResourceProvisioner { func (c *MockEvalContext) Provisioner(n string) provisioners.Interface {
c.ProvisionerCalled = true c.ProvisionerCalled = true
c.ProvisionerName = n c.ProvisionerName = n
return c.ProvisionerProvisioner return c.ProvisionerProvisioner

View File

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"github.com/hashicorp/terraform/configs/configschema" "github.com/hashicorp/terraform/configs/configschema"
"github.com/hashicorp/terraform/provisioners"
) )
// EvalInitProvisioner is an EvalNode implementation that initializes a provisioner // EvalInitProvisioner is an EvalNode implementation that initializes a provisioner
@ -32,7 +33,7 @@ func (n *EvalCloseProvisioner) Eval(ctx EvalContext) (interface{}, error) {
// initialized provisioner instance for the given name. // initialized provisioner instance for the given name.
type EvalGetProvisioner struct { type EvalGetProvisioner struct {
Name string Name string
Output *ResourceProvisioner Output *provisioners.Interface
Schema **configschema.Block Schema **configschema.Block
} }

View File

@ -9,6 +9,7 @@ import (
"github.com/hashicorp/terraform/configs" "github.com/hashicorp/terraform/configs"
"github.com/hashicorp/terraform/configs/configschema" "github.com/hashicorp/terraform/configs/configschema"
"github.com/hashicorp/terraform/providers" "github.com/hashicorp/terraform/providers"
"github.com/hashicorp/terraform/provisioners"
"github.com/hashicorp/terraform/tfdiags" "github.com/hashicorp/terraform/tfdiags"
"github.com/zclconf/go-cty/cty" "github.com/zclconf/go-cty/cty"
"github.com/zclconf/go-cty/cty/convert" "github.com/zclconf/go-cty/cty/convert"
@ -111,7 +112,7 @@ func (n *EvalValidateProvider) Eval(ctx EvalContext) (interface{}, error) {
// the configuration of a provisioner belonging to a resource. // the configuration of a provisioner belonging to a resource.
type EvalValidateProvisioner struct { type EvalValidateProvisioner struct {
ResourceAddr addrs.Resource ResourceAddr addrs.Resource
Provisioner *ResourceProvisioner Provisioner *provisioners.Interface
Schema **configschema.Block Schema **configschema.Block
Config *configs.Provisioner Config *configs.Provisioner
ConnConfig *configs.Connection ConnConfig *configs.Connection
@ -123,9 +124,6 @@ func (n *EvalValidateProvisioner) Eval(ctx EvalContext) (interface{}, error) {
config := *n.Config config := *n.Config
schema := *n.Schema schema := *n.Schema
var warns []string
var errs []error
var diags tfdiags.Diagnostics var diags tfdiags.Diagnostics
{ {
@ -142,22 +140,12 @@ func (n *EvalValidateProvisioner) Eval(ctx EvalContext) (interface{}, error) {
return nil, fmt.Errorf("EvaluateBlock returned nil value") return nil, fmt.Errorf("EvaluateBlock returned nil value")
} }
// The provisioner API still uses our legacy ResourceConfig type, so req := provisioners.ValidateProvisionerConfigRequest{
// we need to shim it. Config: configVal,
legacyRC := NewResourceConfigShimmed(configVal, schema)
w, e := provisioner.Validate(legacyRC)
warns = append(warns, w...)
errs = append(errs, e...)
// FIXME: Once the provisioner API itself returns diagnostics, just
// return diags.NonFatalErr() here.
for _, warn := range warns {
diags = diags.Append(tfdiags.SimpleWarning(warn))
}
for _, err := range errs {
diags = diags.Append(err)
} }
resp := provisioner.ValidateProvisionerConfig(req)
diags = diags.Append(resp.Diagnostics)
} }
{ {

View File

@ -12,6 +12,7 @@ import (
"github.com/hashicorp/terraform/dag" "github.com/hashicorp/terraform/dag"
"github.com/hashicorp/terraform/plans" "github.com/hashicorp/terraform/plans"
"github.com/hashicorp/terraform/providers" "github.com/hashicorp/terraform/providers"
"github.com/hashicorp/terraform/provisioners"
"github.com/hashicorp/terraform/states" "github.com/hashicorp/terraform/states"
"github.com/hashicorp/terraform/tfdiags" "github.com/hashicorp/terraform/tfdiags"
) )
@ -42,7 +43,7 @@ type ContextGraphWalker struct {
providerCache map[string]providers.Interface providerCache map[string]providers.Interface
providerSchemas map[string]*ProviderSchema providerSchemas map[string]*ProviderSchema
providerLock sync.Mutex providerLock sync.Mutex
provisionerCache map[string]ResourceProvisioner provisionerCache map[string]provisioners.Interface
provisionerSchemas map[string]*configschema.Block provisionerSchemas map[string]*configschema.Block
provisionerLock sync.Mutex provisionerLock sync.Mutex
} }
@ -142,7 +143,7 @@ func (w *ContextGraphWalker) init() {
w.contexts = make(map[string]*BuiltinEvalContext) w.contexts = make(map[string]*BuiltinEvalContext)
w.providerCache = make(map[string]providers.Interface) w.providerCache = make(map[string]providers.Interface)
w.providerSchemas = make(map[string]*ProviderSchema) w.providerSchemas = make(map[string]*ProviderSchema)
w.provisionerCache = make(map[string]ResourceProvisioner) w.provisionerCache = make(map[string]provisioners.Interface)
w.provisionerSchemas = make(map[string]*configschema.Block) w.provisionerSchemas = make(map[string]*configschema.Block)
w.variableValues = make(map[string]map[string]cty.Value) w.variableValues = make(map[string]map[string]cty.Value)

View File

@ -3,6 +3,7 @@ package terraform
import ( import (
"github.com/hashicorp/terraform/configs/configschema" "github.com/hashicorp/terraform/configs/configschema"
"github.com/hashicorp/terraform/providers" "github.com/hashicorp/terraform/providers"
"github.com/hashicorp/terraform/provisioners"
"github.com/zclconf/go-cty/cty" "github.com/zclconf/go-cty/cty"
) )
@ -55,7 +56,7 @@ func (n *NodeValidatableResource) EvalTree() EvalNode {
// Validate all the provisioners // Validate all the provisioners
for _, p := range managed.Provisioners { for _, p := range managed.Provisioners {
var provisioner ResourceProvisioner var provisioner provisioners.Interface
var provisionerSchema *configschema.Block var provisionerSchema *configschema.Block
seq.Nodes = append( seq.Nodes = append(
seq.Nodes, seq.Nodes,

View File

@ -2,6 +2,7 @@ package terraform
import ( import (
"github.com/hashicorp/terraform/configs/configschema" "github.com/hashicorp/terraform/configs/configschema"
"github.com/hashicorp/terraform/provisioners"
) )
// ResourceProvisioner is an interface that must be implemented by any // ResourceProvisioner is an interface that must be implemented by any
@ -63,3 +64,7 @@ type ResourceProvisionerCloser interface {
// ResourceProvisionerFactory is a function type that creates a new instance // ResourceProvisionerFactory is a function type that creates a new instance
// of a resource provisioner. // of a resource provisioner.
type ResourceProvisionerFactory func() (ResourceProvisioner, error) type ResourceProvisionerFactory func() (ResourceProvisioner, error)
// ProvisionerFactory is a function type that creates a new instance
// of a provisioners.Interface.
type ProvisionerFactory func() (provisioners.Interface, error)

View File

@ -199,18 +199,18 @@ func loadProvisionerSchemas(schemas map[string]*configschema.Block, config *conf
} }
}() }()
schema, err := provisioner.GetConfigSchema() resp := provisioner.GetSchema()
if err != nil { if resp.Diagnostics.HasErrors() {
// We'll put a stub in the map so we won't re-attempt this on // We'll put a stub in the map so we won't re-attempt this on
// future calls. // future calls.
schemas[name] = &configschema.Block{} schemas[name] = &configschema.Block{}
diags = diags.Append( diags = diags.Append(
fmt.Errorf("Failed to retrieve schema from provisioner %q: %s", name, err), fmt.Errorf("Failed to retrieve schema from provisioner %q: %s", name, resp.Diagnostics.Err()),
) )
return return
} }
schemas[name] = schema schemas[name] = resp.Provisioner
} }
if config != nil { if config != nil {