From ba3ee00837d941c8a2046d52337f59f6cd0920af Mon Sep 17 00:00:00 2001 From: Martin Atkins Date: Tue, 18 Apr 2017 16:54:11 -0700 Subject: [PATCH] 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. --- terraform/resource_provider.go | 50 ++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/terraform/resource_provider.go b/terraform/resource_provider.go index 1a68c8699..949d426e7 100644 --- a/terraform/resource_provider.go +++ b/terraform/resource_provider.go @@ -1,5 +1,11 @@ package terraform +import ( + "fmt" + + "github.com/hashicorp/terraform/plugin/discovery" +) + // ResourceProvider is an interface that must be implemented by any // resource provider: the thing that creates and manages the resources in // a Terraform configuration. @@ -171,6 +177,50 @@ type DataSource struct { 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 // of a resource provider. type ResourceProviderFactory func() (ResourceProvider, error)