core: ResourceProviderResolver interface

ResourceProviderResolver is an extra level of indirection before we
get to a map[string]ResourceProviderFactory, which accepts a map of
version constraints and uses it to choose from potentially-many available
versions of each provider to produce a single ResourceProviderFactory
for each one requested.

As of this commit the ResourceProviderResolver interface is not used. In
a future commit the ContextOpts.Providers map will be replaced with a
resolver instance, with the creation of the factory delayed until the
version constraints have been resolved.
This commit is contained in:
Martin Atkins 2017-04-18 16:54:11 -07:00
parent d6b6dbb5c6
commit ba3ee00837
1 changed files with 50 additions and 0 deletions

View File

@ -1,5 +1,11 @@
package terraform package terraform
import (
"fmt"
"github.com/hashicorp/terraform/plugin/discovery"
)
// ResourceProvider is an interface that must be implemented by any // ResourceProvider is an interface that must be implemented by any
// resource provider: the thing that creates and manages the resources in // resource provider: the thing that creates and manages the resources in
// a Terraform configuration. // a Terraform configuration.
@ -171,6 +177,50 @@ type DataSource struct {
Name string Name string
} }
// ResourceProviderResolver is an interface implemented by objects that are
// able to resolve a given set of resource provider version constraints
// into ResourceProviderFactory callbacks.
type ResourceProviderResolver interface {
// Given a constraint map, return a ResourceProviderFactory for each
// requested provider. If some or all of the constraints cannot be
// satisfied, return a non-nil slice of errors describing the problems.
ResolveProviders(reqd discovery.PluginRequirements) (map[string]ResourceProviderFactory, []error)
}
// ResourceProviderResolverFunc wraps a callback function and turns it into
// a ResourceProviderResolver implementation, for convenience in situations
// where a function and its associated closure are sufficient as a resolver
// implementation.
type ResourceProviderResolverFunc func(reqd discovery.PluginRequirements) (map[string]ResourceProviderFactory, []error)
// ResolveProviders implements ResourceProviderResolver by calling the
// wrapped function.
func (f ResourceProviderResolverFunc) ResolveProviders(reqd discovery.PluginRequirements) (map[string]ResourceProviderFactory, []error) {
return f(reqd)
}
// ResourceProviderResolverFixed returns a ResourceProviderResolver that
// has a fixed set of provider factories provided by the caller. The returned
// resolver ignores version constraints entirely and just returns the given
// factory for each requested provider name.
//
// This function is primarily used in tests, to provide mock providers or
// in-process providers under test.
func ResourceProviderResolverFixed(factories map[string]ResourceProviderFactory) ResourceProviderResolver {
return ResourceProviderResolverFunc(func(reqd discovery.PluginRequirements) (map[string]ResourceProviderFactory, []error) {
ret := make(map[string]ResourceProviderFactory, len(reqd))
var errs []error
for name := range reqd {
if factory, exists := factories[name]; exists {
ret[name] = factory
} else {
errs = append(errs, fmt.Errorf("provider %q is not available", name))
}
}
return ret, errs
})
}
// ResourceProviderFactory is a function type that creates a new instance // ResourceProviderFactory is a function type that creates a new instance
// of a resource provider. // of a resource provider.
type ResourceProviderFactory func() (ResourceProvider, error) type ResourceProviderFactory func() (ResourceProvider, error)