]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blobdiff - vendor/github.com/hashicorp/terraform/plugin/serve.go
Upgrade to 0.12
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / hashicorp / terraform / plugin / serve.go
index 2028a613ff4fd79bca77272498ece0aaf9b15f17..8d056c591aef0d22fb8451e8607e8c3109a94f35 100644 (file)
@@ -2,14 +2,23 @@ package plugin
 
 import (
        "github.com/hashicorp/go-plugin"
+       grpcplugin "github.com/hashicorp/terraform/helper/plugin"
+       proto "github.com/hashicorp/terraform/internal/tfplugin5"
        "github.com/hashicorp/terraform/terraform"
 )
 
-// The constants below are the names of the plugins that can be dispensed
-// from the plugin server.
 const (
+       // The constants below are the names of the plugins that can be dispensed
+       // from the plugin server.
        ProviderPluginName    = "provider"
        ProvisionerPluginName = "provisioner"
+
+       // DefaultProtocolVersion is the protocol version assumed for legacy clients that don't specify
+       // a particular version during their handshake. This is the version used when Terraform 0.10
+       // and 0.11 launch plugins that were built with support for both versions 4 and 5, and must
+       // stay unchanged at 4 until we intentionally build plugins that are not compatible with 0.10 and
+       // 0.11.
+       DefaultProtocolVersion = 4
 )
 
 // Handshake is the HandshakeConfig used to configure clients and servers.
@@ -19,7 +28,7 @@ var Handshake = plugin.HandshakeConfig{
        // one or the other that makes it so that they can't safely communicate.
        // This could be adding a new interface value, it could be how
        // helper/schema computes diffs, etc.
-       ProtocolVersion: 4,
+       ProtocolVersion: DefaultProtocolVersion,
 
        // The magic cookie values should NEVER be changed.
        MagicCookieKey:   "TF_PLUGIN_MAGIC_COOKIE",
@@ -28,27 +37,85 @@ 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 {
+               provisioner := grpcplugin.NewGRPCProvisionerServerShim(opts.ProvisionerFunc())
+               if provisioner != nil {
+                       opts.GRPCProvisionerFunc = func() proto.ProvisionerServer {
+                               return provisioner
+                       }
+               }
+       }
+
        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.
-func pluginMap(opts *ServeOpts) map[string]plugin.Plugin {
+// pluginMap returns the legacy map[string]plugin.Plugin to use for configuring
+// a plugin server or client.
+func legacyPluginMap(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: legacyPluginMap(opts),
+       }
+
+       // add the new protocol versions if they're configured
+       if opts.GRPCProviderFunc != nil || opts.GRPCProvisionerFunc != nil {
+               plugins[5] = plugin.PluginSet{}
+               if opts.GRPCProviderFunc != nil {
+                       plugins[5]["provider"] = &GRPCProviderPlugin{
+                               GRPCProvider: opts.GRPCProviderFunc,
+                       }
+               }
+               if opts.GRPCProvisionerFunc != nil {
+                       plugins[5]["provisioner"] = &GRPCProvisionerPlugin{
+                               GRPCProvisioner: opts.GRPCProvisionerFunc,
+                       }
+               }
        }
+       return plugins
 }