github.com/opentofu/opentofu@v1.7.1/internal/plugin/serve.go (about) 1 // Copyright (c) The OpenTofu Authors 2 // SPDX-License-Identifier: MPL-2.0 3 // Copyright (c) 2023 HashiCorp, Inc. 4 // SPDX-License-Identifier: MPL-2.0 5 6 package plugin 7 8 import ( 9 "github.com/hashicorp/go-plugin" 10 proto "github.com/opentofu/opentofu/internal/tfplugin5" 11 ) 12 13 const ( 14 // The constants below are the names of the plugins that can be dispensed 15 // from the plugin server. 16 ProviderPluginName = "provider" 17 ProvisionerPluginName = "provisioner" 18 19 // DefaultProtocolVersion is the protocol version assumed for legacy clients that don't specify 20 // a particular version during their handshake. This is the version used when Terraform 0.10 21 // and 0.11 launch plugins that were built with support for both versions 4 and 5, and must 22 // stay unchanged at 4 until we intentionally build plugins that are not compatible with 0.10 and 23 // 0.11. 24 DefaultProtocolVersion = 4 25 ) 26 27 // Handshake is the HandshakeConfig used to configure clients and servers. 28 var Handshake = plugin.HandshakeConfig{ 29 // The ProtocolVersion is the version that must match between TF core 30 // and TF plugins. This should be bumped whenever a change happens in 31 // one or the other that makes it so that they can't safely communicate. 32 // This could be adding a new interface value, it could be how 33 // helper/schema computes diffs, etc. 34 ProtocolVersion: DefaultProtocolVersion, 35 36 // The magic cookie values should NEVER be changed. 37 MagicCookieKey: "TF_PLUGIN_MAGIC_COOKIE", 38 MagicCookieValue: "d602bf8f470bc67ca7faa0386276bbdd4330efaf76d1a219cb4d6991ca9872b2", 39 } 40 41 type GRPCProviderFunc func() proto.ProviderServer 42 type GRPCProvisionerFunc func() proto.ProvisionerServer 43 44 // ServeOpts are the configurations to serve a plugin. 45 type ServeOpts struct { 46 // Wrapped versions of the above plugins will automatically shimmed and 47 // added to the GRPC functions when possible. 48 GRPCProviderFunc GRPCProviderFunc 49 GRPCProvisionerFunc GRPCProvisionerFunc 50 } 51 52 // Serve serves a plugin. This function never returns and should be the final 53 // function called in the main function of the plugin. 54 func Serve(opts *ServeOpts) { 55 plugin.Serve(&plugin.ServeConfig{ 56 HandshakeConfig: Handshake, 57 VersionedPlugins: pluginSet(opts), 58 GRPCServer: plugin.DefaultGRPCServer, 59 }) 60 } 61 62 func pluginSet(opts *ServeOpts) map[int]plugin.PluginSet { 63 plugins := map[int]plugin.PluginSet{} 64 65 // add the new protocol versions if they're configured 66 if opts.GRPCProviderFunc != nil || opts.GRPCProvisionerFunc != nil { 67 plugins[5] = plugin.PluginSet{} 68 if opts.GRPCProviderFunc != nil { 69 plugins[5]["provider"] = &GRPCProviderPlugin{ 70 GRPCProvider: opts.GRPCProviderFunc, 71 } 72 } 73 if opts.GRPCProvisionerFunc != nil { 74 plugins[5]["provisioner"] = &GRPCProvisionerPlugin{ 75 GRPCProvisioner: opts.GRPCProvisionerFunc, 76 } 77 } 78 } 79 return plugins 80 }