serve the new version 5 grpc plugins
Use the new go-plugin version negotiation to server th appropriate plugin type when the client requests protocol version 5.
This commit is contained in:
parent
ff7d51a9b4
commit
b403023841
|
@ -5,6 +5,7 @@ import (
|
|||
"errors"
|
||||
"sync"
|
||||
|
||||
plugin "github.com/hashicorp/go-plugin"
|
||||
"github.com/hashicorp/terraform/plugin/proto"
|
||||
"github.com/hashicorp/terraform/providers"
|
||||
"github.com/hashicorp/terraform/version"
|
||||
|
@ -12,6 +13,25 @@ import (
|
|||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
// GRPCProviderPlugin implements plugin.GRPCPlugin for the go-plugin package.
|
||||
type GRPCProviderPlugin struct {
|
||||
plugin.Plugin
|
||||
GRPCProvider func() proto.ProviderServer
|
||||
}
|
||||
|
||||
func (p *GRPCProviderPlugin) GRPCClient(ctx context.Context, broker *plugin.GRPCBroker, c *grpc.ClientConn) (interface{}, error) {
|
||||
return &GRPCProvider{
|
||||
conn: c,
|
||||
client: proto.NewProviderClient(c),
|
||||
ctx: ctx,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p *GRPCProviderPlugin) GRPCServer(broker *plugin.GRPCBroker, s *grpc.Server) error {
|
||||
proto.RegisterProviderServer(s, p.GRPCProvider())
|
||||
return nil
|
||||
}
|
||||
|
||||
// GRPCProvider handles the client, or core side of the plugin rpc connection.
|
||||
// The GRPCProvider methods are mostly a translation layer between the
|
||||
// terraform provioders types and the grpc proto types, directly converting
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"io"
|
||||
"sync"
|
||||
|
||||
plugin "github.com/hashicorp/go-plugin"
|
||||
"github.com/hashicorp/terraform/configs/configschema"
|
||||
"github.com/hashicorp/terraform/plugin/proto"
|
||||
"github.com/hashicorp/terraform/provisioners"
|
||||
|
@ -14,6 +15,25 @@ import (
|
|||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
// GRPCProvisionerPlugin is the plugin.GRPCPlugin implementation.
|
||||
type GRPCProvisionerPlugin struct {
|
||||
plugin.Plugin
|
||||
GRPCProvisioner func() proto.ProvisionerServer
|
||||
}
|
||||
|
||||
func (p *GRPCProvisionerPlugin) GRPCClient(ctx context.Context, broker *plugin.GRPCBroker, c *grpc.ClientConn) (interface{}, error) {
|
||||
return &GRPCProvisioner{
|
||||
conn: c,
|
||||
client: proto.NewProvisionerClient(c),
|
||||
ctx: ctx,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p *GRPCProvisionerPlugin) GRPCServer(broker *plugin.GRPCBroker, s *grpc.Server) error {
|
||||
proto.RegisterProvisionerServer(s, p.GRPCProvisioner())
|
||||
return nil
|
||||
}
|
||||
|
||||
// provisioners.Interface grpc implementation
|
||||
type GRPCProvisioner struct {
|
||||
conn *grpc.ClientConn
|
||||
|
|
|
@ -9,11 +9,14 @@ import (
|
|||
|
||||
// ResourceProviderPlugin is the plugin.Plugin implementation.
|
||||
type ResourceProviderPlugin struct {
|
||||
F func() terraform.ResourceProvider
|
||||
ResourceProvider func() terraform.ResourceProvider
|
||||
}
|
||||
|
||||
func (p *ResourceProviderPlugin) Server(b *plugin.MuxBroker) (interface{}, error) {
|
||||
return &ResourceProviderServer{Broker: b, Provider: p.F()}, nil
|
||||
return &ResourceProviderServer{
|
||||
Broker: b,
|
||||
Provider: p.ResourceProvider(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p *ResourceProviderPlugin) Client(
|
||||
|
|
|
@ -10,11 +10,14 @@ import (
|
|||
|
||||
// ResourceProvisionerPlugin is the plugin.Plugin implementation.
|
||||
type ResourceProvisionerPlugin struct {
|
||||
F func() terraform.ResourceProvisioner
|
||||
ResourceProvisioner func() terraform.ResourceProvisioner
|
||||
}
|
||||
|
||||
func (p *ResourceProvisionerPlugin) Server(b *plugin.MuxBroker) (interface{}, error) {
|
||||
return &ResourceProvisionerServer{Broker: b, Provisioner: p.F()}, nil
|
||||
return &ResourceProvisionerServer{
|
||||
Broker: b,
|
||||
Provisioner: p.ResourceProvisioner(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p *ResourceProvisionerPlugin) Client(
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue