|
|
|
|
@ -2,6 +2,8 @@ package plugin
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"github.com/hashicorp/go-plugin"
|
|
|
|
|
grpcplugin "github.com/hashicorp/terraform/helper/plugin"
|
|
|
|
|
"github.com/hashicorp/terraform/plugin/proto"
|
|
|
|
|
"github.com/hashicorp/terraform/terraform"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
@ -28,27 +30,82 @@ var Handshake = plugin.HandshakeConfig{
|
|
|
|
|
|
|
|
|
|
type ProviderFunc func() terraform.ResourceProvider
|
|
|
|
|
type ProvisionerFunc func() terraform.ResourceProvisioner
|
|
|
|
|
type GRPCProviderFunc func() proto.ProviderServer
|
|
|
|
|
type GRPCProvisionerFunc func() proto.ProvisionerServer
|
|
|
|
|
|
|
|
|
|
// ServeOpts are the configurations to serve a plugin.
|
|
|
|
|
type ServeOpts struct {
|
|
|
|
|
ProviderFunc ProviderFunc
|
|
|
|
|
ProvisionerFunc ProvisionerFunc
|
|
|
|
|
|
|
|
|
|
// Wrapped versions of the above plugins will automatically shimmed and
|
|
|
|
|
// added to the GRPC functions when possible.
|
|
|
|
|
GRPCProviderFunc GRPCProviderFunc
|
|
|
|
|
GRPCProvisionerFunc GRPCProvisionerFunc
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Serve serves a plugin. This function never returns and should be the final
|
|
|
|
|
// function called in the main function of the plugin.
|
|
|
|
|
func Serve(opts *ServeOpts) {
|
|
|
|
|
// since the plugins may not yet be aware of the new protocol, we
|
|
|
|
|
// automatically wrap the plugins in the grpc shims.
|
|
|
|
|
if opts.GRPCProviderFunc == nil && opts.ProviderFunc != nil {
|
|
|
|
|
provider := grpcplugin.NewGRPCProviderServerShim(opts.ProviderFunc())
|
|
|
|
|
// this is almost always going to be a *schema.Provider, but check that
|
|
|
|
|
// we got back a valid provider just in case.
|
|
|
|
|
if provider != nil {
|
|
|
|
|
opts.GRPCProviderFunc = func() proto.ProviderServer {
|
|
|
|
|
return provider
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if opts.GRPCProvisionerFunc == nil && opts.ProvisionerFunc != nil {
|
|
|
|
|
provider := grpcplugin.NewGRPCProvisionerServerShim(opts.ProvisionerFunc())
|
|
|
|
|
if provider != nil {
|
|
|
|
|
opts.GRPCProvisionerFunc = func() proto.ProvisionerServer {
|
|
|
|
|
return provider
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
plugin.Serve(&plugin.ServeConfig{
|
|
|
|
|
HandshakeConfig: Handshake,
|
|
|
|
|
Plugins: pluginMap(opts),
|
|
|
|
|
HandshakeConfig: Handshake,
|
|
|
|
|
VersionedPlugins: pluginSet(opts),
|
|
|
|
|
GRPCServer: plugin.DefaultGRPCServer,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// pluginMap returns the map[string]plugin.Plugin to use for configuring a plugin
|
|
|
|
|
// server or client.
|
|
|
|
|
// pluginMap returns the legacy map[string]plugin.Plugin to use for configuring
|
|
|
|
|
// a plugin server or client.
|
|
|
|
|
func pluginMap(opts *ServeOpts) map[string]plugin.Plugin {
|
|
|
|
|
return map[string]plugin.Plugin{
|
|
|
|
|
"provider": &ResourceProviderPlugin{F: opts.ProviderFunc},
|
|
|
|
|
"provisioner": &ResourceProvisionerPlugin{F: opts.ProvisionerFunc},
|
|
|
|
|
"provider": &ResourceProviderPlugin{
|
|
|
|
|
ResourceProvider: opts.ProviderFunc,
|
|
|
|
|
},
|
|
|
|
|
"provisioner": &ResourceProvisionerPlugin{
|
|
|
|
|
ResourceProvisioner: opts.ProvisionerFunc,
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func pluginSet(opts *ServeOpts) map[int]plugin.PluginSet {
|
|
|
|
|
// Set the legacy netrpc plugins at version 4.
|
|
|
|
|
// The oldest version is returned in when executed by a legacy go-plugin
|
|
|
|
|
// client.
|
|
|
|
|
plugins := map[int]plugin.PluginSet{
|
|
|
|
|
4: pluginMap(opts),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// add the new protocol versions if they're configured
|
|
|
|
|
if opts.GRPCProviderFunc != nil || opts.GRPCProvisionerFunc != nil {
|
|
|
|
|
plugins[5] = plugin.PluginSet{
|
|
|
|
|
"provider": &GRPCProviderPlugin{
|
|
|
|
|
GRPCProvider: opts.GRPCProviderFunc,
|
|
|
|
|
},
|
|
|
|
|
"provisioner": &GRPCProvisionerPlugin{
|
|
|
|
|
GRPCProvisioner: opts.GRPCProvisionerFunc,
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return plugins
|
|
|
|
|
}
|
|
|
|
|
|