Merge pull request #27078 from hashicorp/jbardin/remove-netrpc-plugin
Remove netrpc plugin
This commit is contained in:
commit
b2d0e20759
|
@ -1,76 +0,0 @@
|
||||||
package terraform
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"reflect"
|
|
||||||
)
|
|
||||||
|
|
||||||
// remoteStateFlatten takes a structure and turns into a flat map[string]string.
|
|
||||||
//
|
|
||||||
// Within the "thing" parameter, only primitive values are allowed. Structs are
|
|
||||||
// not supported. Therefore, it can only be slices, maps, primitives, and
|
|
||||||
// any combination of those together.
|
|
||||||
//
|
|
||||||
// The difference between this version and the version in package flatmap is that
|
|
||||||
// we add the count key for maps in this version, and return a normal
|
|
||||||
// map[string]string instead of a flatmap.Map
|
|
||||||
func remoteStateFlatten(thing map[string]interface{}) map[string]string {
|
|
||||||
result := make(map[string]string)
|
|
||||||
|
|
||||||
for k, raw := range thing {
|
|
||||||
flatten(result, k, reflect.ValueOf(raw))
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
func flatten(result map[string]string, prefix string, v reflect.Value) {
|
|
||||||
if v.Kind() == reflect.Interface {
|
|
||||||
v = v.Elem()
|
|
||||||
}
|
|
||||||
|
|
||||||
switch v.Kind() {
|
|
||||||
case reflect.Bool:
|
|
||||||
if v.Bool() {
|
|
||||||
result[prefix] = "true"
|
|
||||||
} else {
|
|
||||||
result[prefix] = "false"
|
|
||||||
}
|
|
||||||
case reflect.Int:
|
|
||||||
result[prefix] = fmt.Sprintf("%d", v.Int())
|
|
||||||
case reflect.Map:
|
|
||||||
flattenMap(result, prefix, v)
|
|
||||||
case reflect.Slice:
|
|
||||||
flattenSlice(result, prefix, v)
|
|
||||||
case reflect.String:
|
|
||||||
result[prefix] = v.String()
|
|
||||||
default:
|
|
||||||
panic(fmt.Sprintf("Unknown: %s", v))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func flattenMap(result map[string]string, prefix string, v reflect.Value) {
|
|
||||||
mapKeys := v.MapKeys()
|
|
||||||
|
|
||||||
result[fmt.Sprintf("%s.%%", prefix)] = fmt.Sprintf("%d", len(mapKeys))
|
|
||||||
for _, k := range mapKeys {
|
|
||||||
if k.Kind() == reflect.Interface {
|
|
||||||
k = k.Elem()
|
|
||||||
}
|
|
||||||
|
|
||||||
if k.Kind() != reflect.String {
|
|
||||||
panic(fmt.Sprintf("%s: map key is not string: %s", prefix, k))
|
|
||||||
}
|
|
||||||
|
|
||||||
flatten(result, fmt.Sprintf("%s.%s", prefix, k.String()), v.MapIndex(k))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func flattenSlice(result map[string]string, prefix string, v reflect.Value) {
|
|
||||||
prefix = prefix + "."
|
|
||||||
|
|
||||||
result[prefix+"#"] = fmt.Sprintf("%d", v.Len())
|
|
||||||
for i := 0; i < v.Len(); i++ {
|
|
||||||
flatten(result, fmt.Sprintf("%s%d", prefix, i), v.Index(i))
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -17,7 +17,7 @@ type Provider struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewProvider returns a new terraform provider
|
// NewProvider returns a new terraform provider
|
||||||
func NewProvider() *Provider {
|
func NewProvider() providers.Interface {
|
||||||
return &Provider{}
|
return &Provider{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,29 +1,10 @@
|
||||||
package terraform
|
package terraform
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/providers"
|
|
||||||
|
|
||||||
backendInit "github.com/hashicorp/terraform/backend/init"
|
backendInit "github.com/hashicorp/terraform/backend/init"
|
||||||
)
|
)
|
||||||
|
|
||||||
var testAccProviders map[string]*Provider
|
|
||||||
var testAccProvider *Provider
|
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
// Initialize the backends
|
// Initialize the backends
|
||||||
backendInit.Init(nil)
|
backendInit.Init(nil)
|
||||||
|
|
||||||
testAccProvider = NewProvider()
|
|
||||||
testAccProviders = map[string]*Provider{
|
|
||||||
"terraform": testAccProvider,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestProvider_impl(t *testing.T) {
|
|
||||||
var _ providers.Interface = NewProvider()
|
|
||||||
}
|
|
||||||
|
|
||||||
func testAccPreCheck(t *testing.T) {
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,6 @@ import (
|
||||||
"github.com/hashicorp/go-plugin"
|
"github.com/hashicorp/go-plugin"
|
||||||
)
|
)
|
||||||
|
|
||||||
// See serve.go for serving plugins
|
|
||||||
|
|
||||||
var VersionedPlugins = map[int]plugin.PluginSet{
|
var VersionedPlugins = map[int]plugin.PluginSet{
|
||||||
5: {
|
5: {
|
||||||
"provider": &GRPCProviderPlugin{},
|
"provider": &GRPCProviderPlugin{},
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
package plugin
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/internal/legacy/terraform"
|
|
||||||
)
|
|
||||||
|
|
||||||
func testProviderFixed(p terraform.ResourceProvider) ProviderFunc {
|
|
||||||
return func() terraform.ResourceProvider {
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testProvisionerFixed(p terraform.ResourceProvisioner) ProvisionerFunc {
|
|
||||||
return func() terraform.ResourceProvisioner {
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,620 +0,0 @@
|
||||||
package plugin
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/rpc"
|
|
||||||
|
|
||||||
plugin "github.com/hashicorp/go-plugin"
|
|
||||||
"github.com/hashicorp/terraform/internal/legacy/terraform"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ResourceProviderPlugin is the plugin.Plugin implementation.
|
|
||||||
type ResourceProviderPlugin struct {
|
|
||||||
ResourceProvider func() terraform.ResourceProvider
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *ResourceProviderPlugin) Server(b *plugin.MuxBroker) (interface{}, error) {
|
|
||||||
return &ResourceProviderServer{
|
|
||||||
Broker: b,
|
|
||||||
Provider: p.ResourceProvider(),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *ResourceProviderPlugin) Client(
|
|
||||||
b *plugin.MuxBroker, c *rpc.Client) (interface{}, error) {
|
|
||||||
return &ResourceProvider{Broker: b, Client: c}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ResourceProvider is an implementation of terraform.ResourceProvider
|
|
||||||
// that communicates over RPC.
|
|
||||||
type ResourceProvider struct {
|
|
||||||
Broker *plugin.MuxBroker
|
|
||||||
Client *rpc.Client
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *ResourceProvider) Stop() error {
|
|
||||||
var resp ResourceProviderStopResponse
|
|
||||||
err := p.Client.Call("Plugin.Stop", new(interface{}), &resp)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if resp.Error != nil {
|
|
||||||
err = resp.Error
|
|
||||||
}
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *ResourceProvider) GetSchema(req *terraform.ProviderSchemaRequest) (*terraform.ProviderSchema, error) {
|
|
||||||
var result ResourceProviderGetSchemaResponse
|
|
||||||
args := &ResourceProviderGetSchemaArgs{
|
|
||||||
Req: req,
|
|
||||||
}
|
|
||||||
|
|
||||||
err := p.Client.Call("Plugin.GetSchema", args, &result)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if result.Error != nil {
|
|
||||||
err = result.Error
|
|
||||||
}
|
|
||||||
|
|
||||||
return result.Schema, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *ResourceProvider) Input(
|
|
||||||
input terraform.UIInput,
|
|
||||||
c *terraform.ResourceConfig) (*terraform.ResourceConfig, error) {
|
|
||||||
id := p.Broker.NextId()
|
|
||||||
go p.Broker.AcceptAndServe(id, &UIInputServer{
|
|
||||||
UIInput: input,
|
|
||||||
})
|
|
||||||
|
|
||||||
var resp ResourceProviderInputResponse
|
|
||||||
args := ResourceProviderInputArgs{
|
|
||||||
InputId: id,
|
|
||||||
Config: c,
|
|
||||||
}
|
|
||||||
|
|
||||||
err := p.Client.Call("Plugin.Input", &args, &resp)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if resp.Error != nil {
|
|
||||||
err = resp.Error
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return resp.Config, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *ResourceProvider) Validate(c *terraform.ResourceConfig) ([]string, []error) {
|
|
||||||
var resp ResourceProviderValidateResponse
|
|
||||||
args := ResourceProviderValidateArgs{
|
|
||||||
Config: c,
|
|
||||||
}
|
|
||||||
|
|
||||||
err := p.Client.Call("Plugin.Validate", &args, &resp)
|
|
||||||
if err != nil {
|
|
||||||
return nil, []error{err}
|
|
||||||
}
|
|
||||||
|
|
||||||
var errs []error
|
|
||||||
if len(resp.Errors) > 0 {
|
|
||||||
errs = make([]error, len(resp.Errors))
|
|
||||||
for i, err := range resp.Errors {
|
|
||||||
errs[i] = err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return resp.Warnings, errs
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *ResourceProvider) ValidateResource(
|
|
||||||
t string, c *terraform.ResourceConfig) ([]string, []error) {
|
|
||||||
var resp ResourceProviderValidateResourceResponse
|
|
||||||
args := ResourceProviderValidateResourceArgs{
|
|
||||||
Config: c,
|
|
||||||
Type: t,
|
|
||||||
}
|
|
||||||
|
|
||||||
err := p.Client.Call("Plugin.ValidateResource", &args, &resp)
|
|
||||||
if err != nil {
|
|
||||||
return nil, []error{err}
|
|
||||||
}
|
|
||||||
|
|
||||||
var errs []error
|
|
||||||
if len(resp.Errors) > 0 {
|
|
||||||
errs = make([]error, len(resp.Errors))
|
|
||||||
for i, err := range resp.Errors {
|
|
||||||
errs[i] = err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return resp.Warnings, errs
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *ResourceProvider) Configure(c *terraform.ResourceConfig) error {
|
|
||||||
var resp ResourceProviderConfigureResponse
|
|
||||||
err := p.Client.Call("Plugin.Configure", c, &resp)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if resp.Error != nil {
|
|
||||||
err = resp.Error
|
|
||||||
}
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *ResourceProvider) Apply(
|
|
||||||
info *terraform.InstanceInfo,
|
|
||||||
s *terraform.InstanceState,
|
|
||||||
d *terraform.InstanceDiff) (*terraform.InstanceState, error) {
|
|
||||||
var resp ResourceProviderApplyResponse
|
|
||||||
args := &ResourceProviderApplyArgs{
|
|
||||||
Info: info,
|
|
||||||
State: s,
|
|
||||||
Diff: d,
|
|
||||||
}
|
|
||||||
|
|
||||||
err := p.Client.Call("Plugin.Apply", args, &resp)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if resp.Error != nil {
|
|
||||||
err = resp.Error
|
|
||||||
}
|
|
||||||
|
|
||||||
return resp.State, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *ResourceProvider) Diff(
|
|
||||||
info *terraform.InstanceInfo,
|
|
||||||
s *terraform.InstanceState,
|
|
||||||
c *terraform.ResourceConfig) (*terraform.InstanceDiff, error) {
|
|
||||||
var resp ResourceProviderDiffResponse
|
|
||||||
args := &ResourceProviderDiffArgs{
|
|
||||||
Info: info,
|
|
||||||
State: s,
|
|
||||||
Config: c,
|
|
||||||
}
|
|
||||||
err := p.Client.Call("Plugin.Diff", args, &resp)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if resp.Error != nil {
|
|
||||||
err = resp.Error
|
|
||||||
}
|
|
||||||
|
|
||||||
return resp.Diff, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *ResourceProvider) ValidateDataSource(
|
|
||||||
t string, c *terraform.ResourceConfig) ([]string, []error) {
|
|
||||||
var resp ResourceProviderValidateResourceResponse
|
|
||||||
args := ResourceProviderValidateResourceArgs{
|
|
||||||
Config: c,
|
|
||||||
Type: t,
|
|
||||||
}
|
|
||||||
|
|
||||||
err := p.Client.Call("Plugin.ValidateDataSource", &args, &resp)
|
|
||||||
if err != nil {
|
|
||||||
return nil, []error{err}
|
|
||||||
}
|
|
||||||
|
|
||||||
var errs []error
|
|
||||||
if len(resp.Errors) > 0 {
|
|
||||||
errs = make([]error, len(resp.Errors))
|
|
||||||
for i, err := range resp.Errors {
|
|
||||||
errs[i] = err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return resp.Warnings, errs
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *ResourceProvider) Refresh(
|
|
||||||
info *terraform.InstanceInfo,
|
|
||||||
s *terraform.InstanceState) (*terraform.InstanceState, error) {
|
|
||||||
var resp ResourceProviderRefreshResponse
|
|
||||||
args := &ResourceProviderRefreshArgs{
|
|
||||||
Info: info,
|
|
||||||
State: s,
|
|
||||||
}
|
|
||||||
|
|
||||||
err := p.Client.Call("Plugin.Refresh", args, &resp)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if resp.Error != nil {
|
|
||||||
err = resp.Error
|
|
||||||
}
|
|
||||||
|
|
||||||
return resp.State, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *ResourceProvider) ImportState(
|
|
||||||
info *terraform.InstanceInfo,
|
|
||||||
id string) ([]*terraform.InstanceState, error) {
|
|
||||||
var resp ResourceProviderImportStateResponse
|
|
||||||
args := &ResourceProviderImportStateArgs{
|
|
||||||
Info: info,
|
|
||||||
Id: id,
|
|
||||||
}
|
|
||||||
|
|
||||||
err := p.Client.Call("Plugin.ImportState", args, &resp)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if resp.Error != nil {
|
|
||||||
err = resp.Error
|
|
||||||
}
|
|
||||||
|
|
||||||
return resp.State, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *ResourceProvider) Resources() []terraform.ResourceType {
|
|
||||||
var result []terraform.ResourceType
|
|
||||||
|
|
||||||
err := p.Client.Call("Plugin.Resources", new(interface{}), &result)
|
|
||||||
if err != nil {
|
|
||||||
// TODO: panic, log, what?
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *ResourceProvider) ReadDataDiff(
|
|
||||||
info *terraform.InstanceInfo,
|
|
||||||
c *terraform.ResourceConfig) (*terraform.InstanceDiff, error) {
|
|
||||||
var resp ResourceProviderReadDataDiffResponse
|
|
||||||
args := &ResourceProviderReadDataDiffArgs{
|
|
||||||
Info: info,
|
|
||||||
Config: c,
|
|
||||||
}
|
|
||||||
|
|
||||||
err := p.Client.Call("Plugin.ReadDataDiff", args, &resp)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if resp.Error != nil {
|
|
||||||
err = resp.Error
|
|
||||||
}
|
|
||||||
|
|
||||||
return resp.Diff, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *ResourceProvider) ReadDataApply(
|
|
||||||
info *terraform.InstanceInfo,
|
|
||||||
d *terraform.InstanceDiff) (*terraform.InstanceState, error) {
|
|
||||||
var resp ResourceProviderReadDataApplyResponse
|
|
||||||
args := &ResourceProviderReadDataApplyArgs{
|
|
||||||
Info: info,
|
|
||||||
Diff: d,
|
|
||||||
}
|
|
||||||
|
|
||||||
err := p.Client.Call("Plugin.ReadDataApply", args, &resp)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if resp.Error != nil {
|
|
||||||
err = resp.Error
|
|
||||||
}
|
|
||||||
|
|
||||||
return resp.State, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *ResourceProvider) DataSources() []terraform.DataSource {
|
|
||||||
var result []terraform.DataSource
|
|
||||||
|
|
||||||
err := p.Client.Call("Plugin.DataSources", new(interface{}), &result)
|
|
||||||
if err != nil {
|
|
||||||
// TODO: panic, log, what?
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *ResourceProvider) Close() error {
|
|
||||||
return p.Client.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
// ResourceProviderServer is a net/rpc compatible structure for serving
|
|
||||||
// a ResourceProvider. This should not be used directly.
|
|
||||||
type ResourceProviderServer struct {
|
|
||||||
Broker *plugin.MuxBroker
|
|
||||||
Provider terraform.ResourceProvider
|
|
||||||
}
|
|
||||||
|
|
||||||
type ResourceProviderStopResponse struct {
|
|
||||||
Error *plugin.BasicError
|
|
||||||
}
|
|
||||||
|
|
||||||
type ResourceProviderGetSchemaArgs struct {
|
|
||||||
Req *terraform.ProviderSchemaRequest
|
|
||||||
}
|
|
||||||
|
|
||||||
type ResourceProviderGetSchemaResponse struct {
|
|
||||||
Schema *terraform.ProviderSchema
|
|
||||||
Error *plugin.BasicError
|
|
||||||
}
|
|
||||||
|
|
||||||
type ResourceProviderConfigureResponse struct {
|
|
||||||
Error *plugin.BasicError
|
|
||||||
}
|
|
||||||
|
|
||||||
type ResourceProviderInputArgs struct {
|
|
||||||
InputId uint32
|
|
||||||
Config *terraform.ResourceConfig
|
|
||||||
}
|
|
||||||
|
|
||||||
type ResourceProviderInputResponse struct {
|
|
||||||
Config *terraform.ResourceConfig
|
|
||||||
Error *plugin.BasicError
|
|
||||||
}
|
|
||||||
|
|
||||||
type ResourceProviderApplyArgs struct {
|
|
||||||
Info *terraform.InstanceInfo
|
|
||||||
State *terraform.InstanceState
|
|
||||||
Diff *terraform.InstanceDiff
|
|
||||||
}
|
|
||||||
|
|
||||||
type ResourceProviderApplyResponse struct {
|
|
||||||
State *terraform.InstanceState
|
|
||||||
Error *plugin.BasicError
|
|
||||||
}
|
|
||||||
|
|
||||||
type ResourceProviderDiffArgs struct {
|
|
||||||
Info *terraform.InstanceInfo
|
|
||||||
State *terraform.InstanceState
|
|
||||||
Config *terraform.ResourceConfig
|
|
||||||
}
|
|
||||||
|
|
||||||
type ResourceProviderDiffResponse struct {
|
|
||||||
Diff *terraform.InstanceDiff
|
|
||||||
Error *plugin.BasicError
|
|
||||||
}
|
|
||||||
|
|
||||||
type ResourceProviderRefreshArgs struct {
|
|
||||||
Info *terraform.InstanceInfo
|
|
||||||
State *terraform.InstanceState
|
|
||||||
}
|
|
||||||
|
|
||||||
type ResourceProviderRefreshResponse struct {
|
|
||||||
State *terraform.InstanceState
|
|
||||||
Error *plugin.BasicError
|
|
||||||
}
|
|
||||||
|
|
||||||
type ResourceProviderImportStateArgs struct {
|
|
||||||
Info *terraform.InstanceInfo
|
|
||||||
Id string
|
|
||||||
}
|
|
||||||
|
|
||||||
type ResourceProviderImportStateResponse struct {
|
|
||||||
State []*terraform.InstanceState
|
|
||||||
Error *plugin.BasicError
|
|
||||||
}
|
|
||||||
|
|
||||||
type ResourceProviderReadDataApplyArgs struct {
|
|
||||||
Info *terraform.InstanceInfo
|
|
||||||
Diff *terraform.InstanceDiff
|
|
||||||
}
|
|
||||||
|
|
||||||
type ResourceProviderReadDataApplyResponse struct {
|
|
||||||
State *terraform.InstanceState
|
|
||||||
Error *plugin.BasicError
|
|
||||||
}
|
|
||||||
|
|
||||||
type ResourceProviderReadDataDiffArgs struct {
|
|
||||||
Info *terraform.InstanceInfo
|
|
||||||
Config *terraform.ResourceConfig
|
|
||||||
}
|
|
||||||
|
|
||||||
type ResourceProviderReadDataDiffResponse struct {
|
|
||||||
Diff *terraform.InstanceDiff
|
|
||||||
Error *plugin.BasicError
|
|
||||||
}
|
|
||||||
|
|
||||||
type ResourceProviderValidateArgs struct {
|
|
||||||
Config *terraform.ResourceConfig
|
|
||||||
}
|
|
||||||
|
|
||||||
type ResourceProviderValidateResponse struct {
|
|
||||||
Warnings []string
|
|
||||||
Errors []*plugin.BasicError
|
|
||||||
}
|
|
||||||
|
|
||||||
type ResourceProviderValidateResourceArgs struct {
|
|
||||||
Config *terraform.ResourceConfig
|
|
||||||
Type string
|
|
||||||
}
|
|
||||||
|
|
||||||
type ResourceProviderValidateResourceResponse struct {
|
|
||||||
Warnings []string
|
|
||||||
Errors []*plugin.BasicError
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ResourceProviderServer) Stop(
|
|
||||||
_ interface{},
|
|
||||||
reply *ResourceProviderStopResponse) error {
|
|
||||||
err := s.Provider.Stop()
|
|
||||||
*reply = ResourceProviderStopResponse{
|
|
||||||
Error: plugin.NewBasicError(err),
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ResourceProviderServer) GetSchema(
|
|
||||||
args *ResourceProviderGetSchemaArgs,
|
|
||||||
result *ResourceProviderGetSchemaResponse,
|
|
||||||
) error {
|
|
||||||
schema, err := s.Provider.GetSchema(args.Req)
|
|
||||||
result.Schema = schema
|
|
||||||
if err != nil {
|
|
||||||
result.Error = plugin.NewBasicError(err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ResourceProviderServer) Input(
|
|
||||||
args *ResourceProviderInputArgs,
|
|
||||||
reply *ResourceProviderInputResponse) error {
|
|
||||||
conn, err := s.Broker.Dial(args.InputId)
|
|
||||||
if err != nil {
|
|
||||||
*reply = ResourceProviderInputResponse{
|
|
||||||
Error: plugin.NewBasicError(err),
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
client := rpc.NewClient(conn)
|
|
||||||
defer client.Close()
|
|
||||||
|
|
||||||
input := &UIInput{Client: client}
|
|
||||||
|
|
||||||
config, err := s.Provider.Input(input, args.Config)
|
|
||||||
*reply = ResourceProviderInputResponse{
|
|
||||||
Config: config,
|
|
||||||
Error: plugin.NewBasicError(err),
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ResourceProviderServer) Validate(
|
|
||||||
args *ResourceProviderValidateArgs,
|
|
||||||
reply *ResourceProviderValidateResponse) error {
|
|
||||||
warns, errs := s.Provider.Validate(args.Config)
|
|
||||||
berrs := make([]*plugin.BasicError, len(errs))
|
|
||||||
for i, err := range errs {
|
|
||||||
berrs[i] = plugin.NewBasicError(err)
|
|
||||||
}
|
|
||||||
*reply = ResourceProviderValidateResponse{
|
|
||||||
Warnings: warns,
|
|
||||||
Errors: berrs,
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ResourceProviderServer) ValidateResource(
|
|
||||||
args *ResourceProviderValidateResourceArgs,
|
|
||||||
reply *ResourceProviderValidateResourceResponse) error {
|
|
||||||
warns, errs := s.Provider.ValidateResource(args.Type, args.Config)
|
|
||||||
berrs := make([]*plugin.BasicError, len(errs))
|
|
||||||
for i, err := range errs {
|
|
||||||
berrs[i] = plugin.NewBasicError(err)
|
|
||||||
}
|
|
||||||
*reply = ResourceProviderValidateResourceResponse{
|
|
||||||
Warnings: warns,
|
|
||||||
Errors: berrs,
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ResourceProviderServer) Configure(
|
|
||||||
config *terraform.ResourceConfig,
|
|
||||||
reply *ResourceProviderConfigureResponse) error {
|
|
||||||
err := s.Provider.Configure(config)
|
|
||||||
*reply = ResourceProviderConfigureResponse{
|
|
||||||
Error: plugin.NewBasicError(err),
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ResourceProviderServer) Apply(
|
|
||||||
args *ResourceProviderApplyArgs,
|
|
||||||
result *ResourceProviderApplyResponse) error {
|
|
||||||
state, err := s.Provider.Apply(args.Info, args.State, args.Diff)
|
|
||||||
*result = ResourceProviderApplyResponse{
|
|
||||||
State: state,
|
|
||||||
Error: plugin.NewBasicError(err),
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ResourceProviderServer) Diff(
|
|
||||||
args *ResourceProviderDiffArgs,
|
|
||||||
result *ResourceProviderDiffResponse) error {
|
|
||||||
diff, err := s.Provider.Diff(args.Info, args.State, args.Config)
|
|
||||||
*result = ResourceProviderDiffResponse{
|
|
||||||
Diff: diff,
|
|
||||||
Error: plugin.NewBasicError(err),
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ResourceProviderServer) Refresh(
|
|
||||||
args *ResourceProviderRefreshArgs,
|
|
||||||
result *ResourceProviderRefreshResponse) error {
|
|
||||||
newState, err := s.Provider.Refresh(args.Info, args.State)
|
|
||||||
*result = ResourceProviderRefreshResponse{
|
|
||||||
State: newState,
|
|
||||||
Error: plugin.NewBasicError(err),
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ResourceProviderServer) ImportState(
|
|
||||||
args *ResourceProviderImportStateArgs,
|
|
||||||
result *ResourceProviderImportStateResponse) error {
|
|
||||||
states, err := s.Provider.ImportState(args.Info, args.Id)
|
|
||||||
*result = ResourceProviderImportStateResponse{
|
|
||||||
State: states,
|
|
||||||
Error: plugin.NewBasicError(err),
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ResourceProviderServer) Resources(
|
|
||||||
nothing interface{},
|
|
||||||
result *[]terraform.ResourceType) error {
|
|
||||||
*result = s.Provider.Resources()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ResourceProviderServer) ValidateDataSource(
|
|
||||||
args *ResourceProviderValidateResourceArgs,
|
|
||||||
reply *ResourceProviderValidateResourceResponse) error {
|
|
||||||
warns, errs := s.Provider.ValidateDataSource(args.Type, args.Config)
|
|
||||||
berrs := make([]*plugin.BasicError, len(errs))
|
|
||||||
for i, err := range errs {
|
|
||||||
berrs[i] = plugin.NewBasicError(err)
|
|
||||||
}
|
|
||||||
*reply = ResourceProviderValidateResourceResponse{
|
|
||||||
Warnings: warns,
|
|
||||||
Errors: berrs,
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ResourceProviderServer) ReadDataDiff(
|
|
||||||
args *ResourceProviderReadDataDiffArgs,
|
|
||||||
result *ResourceProviderReadDataDiffResponse) error {
|
|
||||||
diff, err := s.Provider.ReadDataDiff(args.Info, args.Config)
|
|
||||||
*result = ResourceProviderReadDataDiffResponse{
|
|
||||||
Diff: diff,
|
|
||||||
Error: plugin.NewBasicError(err),
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ResourceProviderServer) ReadDataApply(
|
|
||||||
args *ResourceProviderReadDataApplyArgs,
|
|
||||||
result *ResourceProviderReadDataApplyResponse) error {
|
|
||||||
newState, err := s.Provider.ReadDataApply(args.Info, args.Diff)
|
|
||||||
*result = ResourceProviderReadDataApplyResponse{
|
|
||||||
State: newState,
|
|
||||||
Error: plugin.NewBasicError(err),
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ResourceProviderServer) DataSources(
|
|
||||||
nothing interface{},
|
|
||||||
result *[]terraform.DataSource) error {
|
|
||||||
*result = s.Provider.DataSources()
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,827 +0,0 @@
|
||||||
package plugin
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"reflect"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/hashicorp/go-plugin"
|
|
||||||
"github.com/hashicorp/terraform/internal/legacy/terraform"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestResourceProvider_impl(t *testing.T) {
|
|
||||||
var _ plugin.Plugin = new(ResourceProviderPlugin)
|
|
||||||
var _ terraform.ResourceProvider = new(ResourceProvider)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestResourceProvider_stop(t *testing.T) {
|
|
||||||
// Create a mock provider
|
|
||||||
p := new(terraform.MockResourceProvider)
|
|
||||||
client, _ := plugin.TestPluginRPCConn(t, legacyPluginMap(&ServeOpts{
|
|
||||||
ProviderFunc: testProviderFixed(p),
|
|
||||||
}), nil)
|
|
||||||
defer client.Close()
|
|
||||||
|
|
||||||
// Request the provider
|
|
||||||
raw, err := client.Dispense(ProviderPluginName)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
provider := raw.(terraform.ResourceProvider)
|
|
||||||
|
|
||||||
// Stop
|
|
||||||
e := provider.Stop()
|
|
||||||
if !p.StopCalled {
|
|
||||||
t.Fatal("stop should be called")
|
|
||||||
}
|
|
||||||
if e != nil {
|
|
||||||
t.Fatalf("bad: %#v", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestResourceProvider_stopErrors(t *testing.T) {
|
|
||||||
p := new(terraform.MockResourceProvider)
|
|
||||||
p.StopReturnError = errors.New("foo")
|
|
||||||
|
|
||||||
// Create a mock provider
|
|
||||||
client, _ := plugin.TestPluginRPCConn(t, legacyPluginMap(&ServeOpts{
|
|
||||||
ProviderFunc: testProviderFixed(p),
|
|
||||||
}), nil)
|
|
||||||
defer client.Close()
|
|
||||||
|
|
||||||
// Request the provider
|
|
||||||
raw, err := client.Dispense(ProviderPluginName)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
provider := raw.(terraform.ResourceProvider)
|
|
||||||
|
|
||||||
// Stop
|
|
||||||
e := provider.Stop()
|
|
||||||
if !p.StopCalled {
|
|
||||||
t.Fatal("stop should be called")
|
|
||||||
}
|
|
||||||
if e == nil {
|
|
||||||
t.Fatal("should have error")
|
|
||||||
}
|
|
||||||
if e.Error() != "foo" {
|
|
||||||
t.Fatalf("bad: %s", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestResourceProvider_input(t *testing.T) {
|
|
||||||
// Create a mock provider
|
|
||||||
p := new(terraform.MockResourceProvider)
|
|
||||||
client, _ := plugin.TestPluginRPCConn(t, legacyPluginMap(&ServeOpts{
|
|
||||||
ProviderFunc: testProviderFixed(p),
|
|
||||||
}), nil)
|
|
||||||
defer client.Close()
|
|
||||||
|
|
||||||
// Request the provider
|
|
||||||
raw, err := client.Dispense(ProviderPluginName)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
provider := raw.(terraform.ResourceProvider)
|
|
||||||
|
|
||||||
input := new(terraform.MockUIInput)
|
|
||||||
|
|
||||||
expected := &terraform.ResourceConfig{
|
|
||||||
Raw: map[string]interface{}{"bar": "baz"},
|
|
||||||
}
|
|
||||||
p.InputReturnConfig = expected
|
|
||||||
|
|
||||||
// Input
|
|
||||||
config := &terraform.ResourceConfig{
|
|
||||||
Raw: map[string]interface{}{"foo": "bar"},
|
|
||||||
}
|
|
||||||
actual, err := provider.Input(input, config)
|
|
||||||
if !p.InputCalled {
|
|
||||||
t.Fatal("input should be called")
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(p.InputConfig, config) {
|
|
||||||
t.Fatalf("bad: %#v", p.InputConfig)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("bad: %#v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !reflect.DeepEqual(actual, expected) {
|
|
||||||
t.Fatalf("bad: %#v", actual)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestResourceProvider_configure(t *testing.T) {
|
|
||||||
// Create a mock provider
|
|
||||||
p := new(terraform.MockResourceProvider)
|
|
||||||
client, _ := plugin.TestPluginRPCConn(t, legacyPluginMap(&ServeOpts{
|
|
||||||
ProviderFunc: testProviderFixed(p),
|
|
||||||
}), nil)
|
|
||||||
defer client.Close()
|
|
||||||
|
|
||||||
// Request the provider
|
|
||||||
raw, err := client.Dispense(ProviderPluginName)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
provider := raw.(terraform.ResourceProvider)
|
|
||||||
|
|
||||||
// Configure
|
|
||||||
config := &terraform.ResourceConfig{
|
|
||||||
Raw: map[string]interface{}{"foo": "bar"},
|
|
||||||
}
|
|
||||||
e := provider.Configure(config)
|
|
||||||
if !p.ConfigureCalled {
|
|
||||||
t.Fatal("configure should be called")
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(p.ConfigureConfig, config) {
|
|
||||||
t.Fatalf("bad: %#v", p.ConfigureConfig)
|
|
||||||
}
|
|
||||||
if e != nil {
|
|
||||||
t.Fatalf("bad: %#v", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestResourceProvider_configure_errors(t *testing.T) {
|
|
||||||
p := new(terraform.MockResourceProvider)
|
|
||||||
p.ConfigureReturnError = errors.New("foo")
|
|
||||||
|
|
||||||
// Create a mock provider
|
|
||||||
client, _ := plugin.TestPluginRPCConn(t, legacyPluginMap(&ServeOpts{
|
|
||||||
ProviderFunc: testProviderFixed(p),
|
|
||||||
}), nil)
|
|
||||||
defer client.Close()
|
|
||||||
|
|
||||||
// Request the provider
|
|
||||||
raw, err := client.Dispense(ProviderPluginName)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
provider := raw.(terraform.ResourceProvider)
|
|
||||||
|
|
||||||
// Configure
|
|
||||||
config := &terraform.ResourceConfig{
|
|
||||||
Raw: map[string]interface{}{"foo": "bar"},
|
|
||||||
}
|
|
||||||
e := provider.Configure(config)
|
|
||||||
if !p.ConfigureCalled {
|
|
||||||
t.Fatal("configure should be called")
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(p.ConfigureConfig, config) {
|
|
||||||
t.Fatalf("bad: %#v", p.ConfigureConfig)
|
|
||||||
}
|
|
||||||
if e == nil {
|
|
||||||
t.Fatal("should have error")
|
|
||||||
}
|
|
||||||
if e.Error() != "foo" {
|
|
||||||
t.Fatalf("bad: %s", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestResourceProvider_configure_warnings(t *testing.T) {
|
|
||||||
p := new(terraform.MockResourceProvider)
|
|
||||||
|
|
||||||
// Create a mock provider
|
|
||||||
client, _ := plugin.TestPluginRPCConn(t, legacyPluginMap(&ServeOpts{
|
|
||||||
ProviderFunc: testProviderFixed(p),
|
|
||||||
}), nil)
|
|
||||||
defer client.Close()
|
|
||||||
|
|
||||||
// Request the provider
|
|
||||||
raw, err := client.Dispense(ProviderPluginName)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
provider := raw.(terraform.ResourceProvider)
|
|
||||||
|
|
||||||
// Configure
|
|
||||||
config := &terraform.ResourceConfig{
|
|
||||||
Raw: map[string]interface{}{"foo": "bar"},
|
|
||||||
}
|
|
||||||
e := provider.Configure(config)
|
|
||||||
if !p.ConfigureCalled {
|
|
||||||
t.Fatal("configure should be called")
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(p.ConfigureConfig, config) {
|
|
||||||
t.Fatalf("bad: %#v", p.ConfigureConfig)
|
|
||||||
}
|
|
||||||
if e != nil {
|
|
||||||
t.Fatalf("bad: %#v", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestResourceProvider_apply(t *testing.T) {
|
|
||||||
p := new(terraform.MockResourceProvider)
|
|
||||||
|
|
||||||
// Create a mock provider
|
|
||||||
client, _ := plugin.TestPluginRPCConn(t, legacyPluginMap(&ServeOpts{
|
|
||||||
ProviderFunc: testProviderFixed(p),
|
|
||||||
}), nil)
|
|
||||||
defer client.Close()
|
|
||||||
|
|
||||||
// Request the provider
|
|
||||||
raw, err := client.Dispense(ProviderPluginName)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
provider := raw.(terraform.ResourceProvider)
|
|
||||||
|
|
||||||
p.ApplyReturn = &terraform.InstanceState{
|
|
||||||
ID: "bob",
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply
|
|
||||||
info := &terraform.InstanceInfo{}
|
|
||||||
state := &terraform.InstanceState{}
|
|
||||||
diff := &terraform.InstanceDiff{}
|
|
||||||
newState, err := provider.Apply(info, state, diff)
|
|
||||||
if !p.ApplyCalled {
|
|
||||||
t.Fatal("apply should be called")
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(p.ApplyDiff, diff) {
|
|
||||||
t.Fatalf("bad: %#v", p.ApplyDiff)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("bad: %#v", err)
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(p.ApplyReturn, newState) {
|
|
||||||
t.Fatalf("bad: %#v", newState)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestResourceProvider_diff(t *testing.T) {
|
|
||||||
p := new(terraform.MockResourceProvider)
|
|
||||||
|
|
||||||
// Create a mock provider
|
|
||||||
client, _ := plugin.TestPluginRPCConn(t, legacyPluginMap(&ServeOpts{
|
|
||||||
ProviderFunc: testProviderFixed(p),
|
|
||||||
}), nil)
|
|
||||||
defer client.Close()
|
|
||||||
|
|
||||||
// Request the provider
|
|
||||||
raw, err := client.Dispense(ProviderPluginName)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
provider := raw.(terraform.ResourceProvider)
|
|
||||||
|
|
||||||
p.DiffReturn = &terraform.InstanceDiff{
|
|
||||||
Attributes: map[string]*terraform.ResourceAttrDiff{
|
|
||||||
"foo": &terraform.ResourceAttrDiff{
|
|
||||||
Old: "",
|
|
||||||
New: "bar",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// Diff
|
|
||||||
info := &terraform.InstanceInfo{}
|
|
||||||
state := &terraform.InstanceState{}
|
|
||||||
config := &terraform.ResourceConfig{
|
|
||||||
Raw: map[string]interface{}{"foo": "bar"},
|
|
||||||
}
|
|
||||||
diff, err := provider.Diff(info, state, config)
|
|
||||||
if !p.DiffCalled {
|
|
||||||
t.Fatal("diff should be called")
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(p.DiffDesired, config) {
|
|
||||||
t.Fatalf("bad: %#v", p.DiffDesired)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("bad: %#v", err)
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(p.DiffReturn, diff) {
|
|
||||||
t.Fatalf("bad: %#v", diff)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestResourceProvider_diff_error(t *testing.T) {
|
|
||||||
p := new(terraform.MockResourceProvider)
|
|
||||||
|
|
||||||
// Create a mock provider
|
|
||||||
client, _ := plugin.TestPluginRPCConn(t, legacyPluginMap(&ServeOpts{
|
|
||||||
ProviderFunc: testProviderFixed(p),
|
|
||||||
}), nil)
|
|
||||||
defer client.Close()
|
|
||||||
|
|
||||||
// Request the provider
|
|
||||||
raw, err := client.Dispense(ProviderPluginName)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
provider := raw.(terraform.ResourceProvider)
|
|
||||||
|
|
||||||
p.DiffReturnError = errors.New("foo")
|
|
||||||
|
|
||||||
// Diff
|
|
||||||
info := &terraform.InstanceInfo{}
|
|
||||||
state := &terraform.InstanceState{}
|
|
||||||
config := &terraform.ResourceConfig{
|
|
||||||
Raw: map[string]interface{}{"foo": "bar"},
|
|
||||||
}
|
|
||||||
diff, err := provider.Diff(info, state, config)
|
|
||||||
if !p.DiffCalled {
|
|
||||||
t.Fatal("diff should be called")
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(p.DiffDesired, config) {
|
|
||||||
t.Fatalf("bad: %#v", p.DiffDesired)
|
|
||||||
}
|
|
||||||
if err == nil {
|
|
||||||
t.Fatal("should have error")
|
|
||||||
}
|
|
||||||
if diff != nil {
|
|
||||||
t.Fatal("should not have diff")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestResourceProvider_refresh(t *testing.T) {
|
|
||||||
p := new(terraform.MockResourceProvider)
|
|
||||||
|
|
||||||
// Create a mock provider
|
|
||||||
client, _ := plugin.TestPluginRPCConn(t, legacyPluginMap(&ServeOpts{
|
|
||||||
ProviderFunc: testProviderFixed(p),
|
|
||||||
}), nil)
|
|
||||||
defer client.Close()
|
|
||||||
|
|
||||||
// Request the provider
|
|
||||||
raw, err := client.Dispense(ProviderPluginName)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
provider := raw.(terraform.ResourceProvider)
|
|
||||||
|
|
||||||
p.RefreshReturn = &terraform.InstanceState{
|
|
||||||
ID: "bob",
|
|
||||||
}
|
|
||||||
|
|
||||||
// Refresh
|
|
||||||
info := &terraform.InstanceInfo{}
|
|
||||||
state := &terraform.InstanceState{}
|
|
||||||
newState, err := provider.Refresh(info, state)
|
|
||||||
if !p.RefreshCalled {
|
|
||||||
t.Fatal("refresh should be called")
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(p.RefreshState, state) {
|
|
||||||
t.Fatalf("bad: %#v", p.RefreshState)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("bad: %#v", err)
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(p.RefreshReturn, newState) {
|
|
||||||
t.Fatalf("bad: %#v", newState)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestResourceProvider_importState(t *testing.T) {
|
|
||||||
p := new(terraform.MockResourceProvider)
|
|
||||||
|
|
||||||
// Create a mock provider
|
|
||||||
client, _ := plugin.TestPluginRPCConn(t, legacyPluginMap(&ServeOpts{
|
|
||||||
ProviderFunc: testProviderFixed(p),
|
|
||||||
}), nil)
|
|
||||||
defer client.Close()
|
|
||||||
|
|
||||||
// Request the provider
|
|
||||||
raw, err := client.Dispense(ProviderPluginName)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
provider := raw.(terraform.ResourceProvider)
|
|
||||||
|
|
||||||
p.ImportStateReturn = []*terraform.InstanceState{
|
|
||||||
&terraform.InstanceState{
|
|
||||||
ID: "bob",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// ImportState
|
|
||||||
info := &terraform.InstanceInfo{}
|
|
||||||
states, err := provider.ImportState(info, "foo")
|
|
||||||
if !p.ImportStateCalled {
|
|
||||||
t.Fatal("ImportState should be called")
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(p.ImportStateInfo, info) {
|
|
||||||
t.Fatalf("bad: %#v", p.ImportStateInfo)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("bad: %#v", err)
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(p.ImportStateReturn, states) {
|
|
||||||
t.Fatalf("bad: %#v", states)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestResourceProvider_resources(t *testing.T) {
|
|
||||||
p := new(terraform.MockResourceProvider)
|
|
||||||
|
|
||||||
// Create a mock provider
|
|
||||||
client, _ := plugin.TestPluginRPCConn(t, legacyPluginMap(&ServeOpts{
|
|
||||||
ProviderFunc: testProviderFixed(p),
|
|
||||||
}), nil)
|
|
||||||
defer client.Close()
|
|
||||||
|
|
||||||
// Request the provider
|
|
||||||
raw, err := client.Dispense(ProviderPluginName)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
provider := raw.(terraform.ResourceProvider)
|
|
||||||
|
|
||||||
expected := []terraform.ResourceType{
|
|
||||||
terraform.ResourceType{Name: "foo"},
|
|
||||||
terraform.ResourceType{Name: "bar", Importable: true},
|
|
||||||
}
|
|
||||||
|
|
||||||
p.ResourcesReturn = expected
|
|
||||||
|
|
||||||
// Resources
|
|
||||||
result := provider.Resources()
|
|
||||||
if !p.ResourcesCalled {
|
|
||||||
t.Fatal("resources should be called")
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(result, expected) {
|
|
||||||
t.Fatalf("bad: %#v", result)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestResourceProvider_readdataapply(t *testing.T) {
|
|
||||||
p := new(terraform.MockResourceProvider)
|
|
||||||
|
|
||||||
// Create a mock provider
|
|
||||||
client, _ := plugin.TestPluginRPCConn(t, legacyPluginMap(&ServeOpts{
|
|
||||||
ProviderFunc: testProviderFixed(p),
|
|
||||||
}), nil)
|
|
||||||
defer client.Close()
|
|
||||||
|
|
||||||
// Request the provider
|
|
||||||
raw, err := client.Dispense(ProviderPluginName)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
provider := raw.(terraform.ResourceProvider)
|
|
||||||
|
|
||||||
p.ReadDataApplyReturn = &terraform.InstanceState{
|
|
||||||
ID: "bob",
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadDataApply
|
|
||||||
info := &terraform.InstanceInfo{}
|
|
||||||
diff := &terraform.InstanceDiff{}
|
|
||||||
newState, err := provider.ReadDataApply(info, diff)
|
|
||||||
if !p.ReadDataApplyCalled {
|
|
||||||
t.Fatal("ReadDataApply should be called")
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(p.ReadDataApplyDiff, diff) {
|
|
||||||
t.Fatalf("bad: %#v", p.ReadDataApplyDiff)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("bad: %#v", err)
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(p.ReadDataApplyReturn, newState) {
|
|
||||||
t.Fatalf("bad: %#v", newState)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestResourceProvider_datasources(t *testing.T) {
|
|
||||||
p := new(terraform.MockResourceProvider)
|
|
||||||
|
|
||||||
// Create a mock provider
|
|
||||||
client, _ := plugin.TestPluginRPCConn(t, legacyPluginMap(&ServeOpts{
|
|
||||||
ProviderFunc: testProviderFixed(p),
|
|
||||||
}), nil)
|
|
||||||
defer client.Close()
|
|
||||||
|
|
||||||
// Request the provider
|
|
||||||
raw, err := client.Dispense(ProviderPluginName)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
provider := raw.(terraform.ResourceProvider)
|
|
||||||
|
|
||||||
expected := []terraform.DataSource{
|
|
||||||
{Name: "foo"},
|
|
||||||
{Name: "bar"},
|
|
||||||
}
|
|
||||||
|
|
||||||
p.DataSourcesReturn = expected
|
|
||||||
|
|
||||||
// DataSources
|
|
||||||
result := provider.DataSources()
|
|
||||||
if !p.DataSourcesCalled {
|
|
||||||
t.Fatal("DataSources should be called")
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(result, expected) {
|
|
||||||
t.Fatalf("bad: %#v", result)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestResourceProvider_validate(t *testing.T) {
|
|
||||||
p := new(terraform.MockResourceProvider)
|
|
||||||
|
|
||||||
// Create a mock provider
|
|
||||||
client, _ := plugin.TestPluginRPCConn(t, legacyPluginMap(&ServeOpts{
|
|
||||||
ProviderFunc: testProviderFixed(p),
|
|
||||||
}), nil)
|
|
||||||
defer client.Close()
|
|
||||||
|
|
||||||
// Request the provider
|
|
||||||
raw, err := client.Dispense(ProviderPluginName)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
provider := raw.(terraform.ResourceProvider)
|
|
||||||
|
|
||||||
// Configure
|
|
||||||
config := &terraform.ResourceConfig{
|
|
||||||
Raw: map[string]interface{}{"foo": "bar"},
|
|
||||||
}
|
|
||||||
w, e := provider.Validate(config)
|
|
||||||
if !p.ValidateCalled {
|
|
||||||
t.Fatal("configure should be called")
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(p.ValidateConfig, config) {
|
|
||||||
t.Fatalf("bad: %#v", p.ValidateConfig)
|
|
||||||
}
|
|
||||||
if w != nil {
|
|
||||||
t.Fatalf("bad: %#v", w)
|
|
||||||
}
|
|
||||||
if e != nil {
|
|
||||||
t.Fatalf("bad: %#v", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestResourceProvider_validate_errors(t *testing.T) {
|
|
||||||
p := new(terraform.MockResourceProvider)
|
|
||||||
|
|
||||||
// Create a mock provider
|
|
||||||
client, _ := plugin.TestPluginRPCConn(t, legacyPluginMap(&ServeOpts{
|
|
||||||
ProviderFunc: testProviderFixed(p),
|
|
||||||
}), nil)
|
|
||||||
defer client.Close()
|
|
||||||
|
|
||||||
// Request the provider
|
|
||||||
raw, err := client.Dispense(ProviderPluginName)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
provider := raw.(terraform.ResourceProvider)
|
|
||||||
|
|
||||||
p.ValidateReturnErrors = []error{errors.New("foo")}
|
|
||||||
|
|
||||||
// Configure
|
|
||||||
config := &terraform.ResourceConfig{
|
|
||||||
Raw: map[string]interface{}{"foo": "bar"},
|
|
||||||
}
|
|
||||||
w, e := provider.Validate(config)
|
|
||||||
if !p.ValidateCalled {
|
|
||||||
t.Fatal("configure should be called")
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(p.ValidateConfig, config) {
|
|
||||||
t.Fatalf("bad: %#v", p.ValidateConfig)
|
|
||||||
}
|
|
||||||
if w != nil {
|
|
||||||
t.Fatalf("bad: %#v", w)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(e) != 1 {
|
|
||||||
t.Fatalf("bad: %#v", e)
|
|
||||||
}
|
|
||||||
if e[0].Error() != "foo" {
|
|
||||||
t.Fatalf("bad: %#v", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestResourceProvider_validate_warns(t *testing.T) {
|
|
||||||
p := new(terraform.MockResourceProvider)
|
|
||||||
|
|
||||||
// Create a mock provider
|
|
||||||
client, _ := plugin.TestPluginRPCConn(t, legacyPluginMap(&ServeOpts{
|
|
||||||
ProviderFunc: testProviderFixed(p),
|
|
||||||
}), nil)
|
|
||||||
defer client.Close()
|
|
||||||
|
|
||||||
// Request the provider
|
|
||||||
raw, err := client.Dispense(ProviderPluginName)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
provider := raw.(terraform.ResourceProvider)
|
|
||||||
|
|
||||||
p.ValidateReturnWarns = []string{"foo"}
|
|
||||||
|
|
||||||
// Configure
|
|
||||||
config := &terraform.ResourceConfig{
|
|
||||||
Raw: map[string]interface{}{"foo": "bar"},
|
|
||||||
}
|
|
||||||
w, e := provider.Validate(config)
|
|
||||||
if !p.ValidateCalled {
|
|
||||||
t.Fatal("configure should be called")
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(p.ValidateConfig, config) {
|
|
||||||
t.Fatalf("bad: %#v", p.ValidateConfig)
|
|
||||||
}
|
|
||||||
if e != nil {
|
|
||||||
t.Fatalf("bad: %#v", e)
|
|
||||||
}
|
|
||||||
|
|
||||||
expected := []string{"foo"}
|
|
||||||
if !reflect.DeepEqual(w, expected) {
|
|
||||||
t.Fatalf("bad: %#v", w)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestResourceProvider_validateResource(t *testing.T) {
|
|
||||||
p := new(terraform.MockResourceProvider)
|
|
||||||
|
|
||||||
// Create a mock provider
|
|
||||||
client, _ := plugin.TestPluginRPCConn(t, legacyPluginMap(&ServeOpts{
|
|
||||||
ProviderFunc: testProviderFixed(p),
|
|
||||||
}), nil)
|
|
||||||
defer client.Close()
|
|
||||||
|
|
||||||
// Request the provider
|
|
||||||
raw, err := client.Dispense(ProviderPluginName)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
provider := raw.(terraform.ResourceProvider)
|
|
||||||
|
|
||||||
// Configure
|
|
||||||
config := &terraform.ResourceConfig{
|
|
||||||
Raw: map[string]interface{}{"foo": "bar"},
|
|
||||||
}
|
|
||||||
w, e := provider.ValidateResource("foo", config)
|
|
||||||
if !p.ValidateResourceCalled {
|
|
||||||
t.Fatal("configure should be called")
|
|
||||||
}
|
|
||||||
if p.ValidateResourceType != "foo" {
|
|
||||||
t.Fatalf("bad: %#v", p.ValidateResourceType)
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(p.ValidateResourceConfig, config) {
|
|
||||||
t.Fatalf("bad: %#v", p.ValidateResourceConfig)
|
|
||||||
}
|
|
||||||
if w != nil {
|
|
||||||
t.Fatalf("bad: %#v", w)
|
|
||||||
}
|
|
||||||
if e != nil {
|
|
||||||
t.Fatalf("bad: %#v", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestResourceProvider_validateResource_errors(t *testing.T) {
|
|
||||||
p := new(terraform.MockResourceProvider)
|
|
||||||
|
|
||||||
// Create a mock provider
|
|
||||||
client, _ := plugin.TestPluginRPCConn(t, legacyPluginMap(&ServeOpts{
|
|
||||||
ProviderFunc: testProviderFixed(p),
|
|
||||||
}), nil)
|
|
||||||
defer client.Close()
|
|
||||||
|
|
||||||
// Request the provider
|
|
||||||
raw, err := client.Dispense(ProviderPluginName)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
provider := raw.(terraform.ResourceProvider)
|
|
||||||
|
|
||||||
p.ValidateResourceReturnErrors = []error{errors.New("foo")}
|
|
||||||
|
|
||||||
// Configure
|
|
||||||
config := &terraform.ResourceConfig{
|
|
||||||
Raw: map[string]interface{}{"foo": "bar"},
|
|
||||||
}
|
|
||||||
w, e := provider.ValidateResource("foo", config)
|
|
||||||
if !p.ValidateResourceCalled {
|
|
||||||
t.Fatal("configure should be called")
|
|
||||||
}
|
|
||||||
if p.ValidateResourceType != "foo" {
|
|
||||||
t.Fatalf("bad: %#v", p.ValidateResourceType)
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(p.ValidateResourceConfig, config) {
|
|
||||||
t.Fatalf("bad: %#v", p.ValidateResourceConfig)
|
|
||||||
}
|
|
||||||
if w != nil {
|
|
||||||
t.Fatalf("bad: %#v", w)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(e) != 1 {
|
|
||||||
t.Fatalf("bad: %#v", e)
|
|
||||||
}
|
|
||||||
if e[0].Error() != "foo" {
|
|
||||||
t.Fatalf("bad: %#v", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestResourceProvider_validateResource_warns(t *testing.T) {
|
|
||||||
p := new(terraform.MockResourceProvider)
|
|
||||||
|
|
||||||
// Create a mock provider
|
|
||||||
client, _ := plugin.TestPluginRPCConn(t, legacyPluginMap(&ServeOpts{
|
|
||||||
ProviderFunc: testProviderFixed(p),
|
|
||||||
}), nil)
|
|
||||||
defer client.Close()
|
|
||||||
|
|
||||||
// Request the provider
|
|
||||||
raw, err := client.Dispense(ProviderPluginName)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
provider := raw.(terraform.ResourceProvider)
|
|
||||||
|
|
||||||
p.ValidateResourceReturnWarns = []string{"foo"}
|
|
||||||
|
|
||||||
// Configure
|
|
||||||
config := &terraform.ResourceConfig{
|
|
||||||
Raw: map[string]interface{}{"foo": "bar"},
|
|
||||||
}
|
|
||||||
w, e := provider.ValidateResource("foo", config)
|
|
||||||
if !p.ValidateResourceCalled {
|
|
||||||
t.Fatal("configure should be called")
|
|
||||||
}
|
|
||||||
if p.ValidateResourceType != "foo" {
|
|
||||||
t.Fatalf("bad: %#v", p.ValidateResourceType)
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(p.ValidateResourceConfig, config) {
|
|
||||||
t.Fatalf("bad: %#v", p.ValidateResourceConfig)
|
|
||||||
}
|
|
||||||
if e != nil {
|
|
||||||
t.Fatalf("bad: %#v", e)
|
|
||||||
}
|
|
||||||
|
|
||||||
expected := []string{"foo"}
|
|
||||||
if !reflect.DeepEqual(w, expected) {
|
|
||||||
t.Fatalf("bad: %#v", w)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestResourceProvider_validateDataSource(t *testing.T) {
|
|
||||||
p := new(terraform.MockResourceProvider)
|
|
||||||
|
|
||||||
// Create a mock provider
|
|
||||||
client, _ := plugin.TestPluginRPCConn(t, legacyPluginMap(&ServeOpts{
|
|
||||||
ProviderFunc: testProviderFixed(p),
|
|
||||||
}), nil)
|
|
||||||
defer client.Close()
|
|
||||||
|
|
||||||
// Request the provider
|
|
||||||
raw, err := client.Dispense(ProviderPluginName)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
provider := raw.(terraform.ResourceProvider)
|
|
||||||
|
|
||||||
// Configure
|
|
||||||
config := &terraform.ResourceConfig{
|
|
||||||
Raw: map[string]interface{}{"foo": "bar"},
|
|
||||||
}
|
|
||||||
w, e := provider.ValidateDataSource("foo", config)
|
|
||||||
if !p.ValidateDataSourceCalled {
|
|
||||||
t.Fatal("configure should be called")
|
|
||||||
}
|
|
||||||
if p.ValidateDataSourceType != "foo" {
|
|
||||||
t.Fatalf("bad: %#v", p.ValidateDataSourceType)
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(p.ValidateDataSourceConfig, config) {
|
|
||||||
t.Fatalf("bad: %#v", p.ValidateDataSourceConfig)
|
|
||||||
}
|
|
||||||
if w != nil {
|
|
||||||
t.Fatalf("bad: %#v", w)
|
|
||||||
}
|
|
||||||
if e != nil {
|
|
||||||
t.Fatalf("bad: %#v", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestResourceProvider_close(t *testing.T) {
|
|
||||||
p := new(terraform.MockResourceProvider)
|
|
||||||
|
|
||||||
// Create a mock provider
|
|
||||||
client, _ := plugin.TestPluginRPCConn(t, legacyPluginMap(&ServeOpts{
|
|
||||||
ProviderFunc: testProviderFixed(p),
|
|
||||||
}), nil)
|
|
||||||
defer client.Close()
|
|
||||||
|
|
||||||
// Request the provider
|
|
||||||
raw, err := client.Dispense(ProviderPluginName)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
provider := raw.(terraform.ResourceProvider)
|
|
||||||
|
|
||||||
var iface interface{} = provider
|
|
||||||
pCloser, ok := iface.(terraform.ResourceProviderCloser)
|
|
||||||
if !ok {
|
|
||||||
t.Fatal("should be a ResourceProviderCloser")
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := pCloser.Close(); err != nil {
|
|
||||||
t.Fatalf("failed to close provider: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// The connection should be closed now, so if we to make a
|
|
||||||
// new call we should get an error.
|
|
||||||
err = provider.Configure(&terraform.ResourceConfig{})
|
|
||||||
if err == nil {
|
|
||||||
t.Fatal("should have error")
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,181 +0,0 @@
|
||||||
package plugin
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/rpc"
|
|
||||||
|
|
||||||
"github.com/hashicorp/go-plugin"
|
|
||||||
"github.com/hashicorp/terraform/configs/configschema"
|
|
||||||
"github.com/hashicorp/terraform/internal/legacy/terraform"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ResourceProvisionerPlugin is the plugin.Plugin implementation.
|
|
||||||
type ResourceProvisionerPlugin struct {
|
|
||||||
ResourceProvisioner func() terraform.ResourceProvisioner
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *ResourceProvisionerPlugin) Server(b *plugin.MuxBroker) (interface{}, error) {
|
|
||||||
return &ResourceProvisionerServer{
|
|
||||||
Broker: b,
|
|
||||||
Provisioner: p.ResourceProvisioner(),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *ResourceProvisionerPlugin) Client(
|
|
||||||
b *plugin.MuxBroker, c *rpc.Client) (interface{}, error) {
|
|
||||||
return &ResourceProvisioner{Broker: b, Client: c}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ResourceProvisioner is an implementation of terraform.ResourceProvisioner
|
|
||||||
// that communicates over RPC.
|
|
||||||
type ResourceProvisioner struct {
|
|
||||||
Broker *plugin.MuxBroker
|
|
||||||
Client *rpc.Client
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *ResourceProvisioner) GetConfigSchema() (*configschema.Block, error) {
|
|
||||||
panic("not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *ResourceProvisioner) Validate(c *terraform.ResourceConfig) ([]string, []error) {
|
|
||||||
var resp ResourceProvisionerValidateResponse
|
|
||||||
args := ResourceProvisionerValidateArgs{
|
|
||||||
Config: c,
|
|
||||||
}
|
|
||||||
|
|
||||||
err := p.Client.Call("Plugin.Validate", &args, &resp)
|
|
||||||
if err != nil {
|
|
||||||
return nil, []error{err}
|
|
||||||
}
|
|
||||||
|
|
||||||
var errs []error
|
|
||||||
if len(resp.Errors) > 0 {
|
|
||||||
errs = make([]error, len(resp.Errors))
|
|
||||||
for i, err := range resp.Errors {
|
|
||||||
errs[i] = err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return resp.Warnings, errs
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *ResourceProvisioner) Apply(
|
|
||||||
output terraform.UIOutput,
|
|
||||||
s *terraform.InstanceState,
|
|
||||||
c *terraform.ResourceConfig) error {
|
|
||||||
id := p.Broker.NextId()
|
|
||||||
go p.Broker.AcceptAndServe(id, &UIOutputServer{
|
|
||||||
UIOutput: output,
|
|
||||||
})
|
|
||||||
|
|
||||||
var resp ResourceProvisionerApplyResponse
|
|
||||||
args := &ResourceProvisionerApplyArgs{
|
|
||||||
OutputId: id,
|
|
||||||
State: s,
|
|
||||||
Config: c,
|
|
||||||
}
|
|
||||||
|
|
||||||
err := p.Client.Call("Plugin.Apply", args, &resp)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if resp.Error != nil {
|
|
||||||
err = resp.Error
|
|
||||||
}
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *ResourceProvisioner) Stop() error {
|
|
||||||
var resp ResourceProvisionerStopResponse
|
|
||||||
err := p.Client.Call("Plugin.Stop", new(interface{}), &resp)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if resp.Error != nil {
|
|
||||||
err = resp.Error
|
|
||||||
}
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *ResourceProvisioner) Close() error {
|
|
||||||
return p.Client.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
type ResourceProvisionerValidateArgs struct {
|
|
||||||
Config *terraform.ResourceConfig
|
|
||||||
}
|
|
||||||
|
|
||||||
type ResourceProvisionerValidateResponse struct {
|
|
||||||
Warnings []string
|
|
||||||
Errors []*plugin.BasicError
|
|
||||||
}
|
|
||||||
|
|
||||||
type ResourceProvisionerApplyArgs struct {
|
|
||||||
OutputId uint32
|
|
||||||
State *terraform.InstanceState
|
|
||||||
Config *terraform.ResourceConfig
|
|
||||||
}
|
|
||||||
|
|
||||||
type ResourceProvisionerApplyResponse struct {
|
|
||||||
Error *plugin.BasicError
|
|
||||||
}
|
|
||||||
|
|
||||||
type ResourceProvisionerStopResponse struct {
|
|
||||||
Error *plugin.BasicError
|
|
||||||
}
|
|
||||||
|
|
||||||
// ResourceProvisionerServer is a net/rpc compatible structure for serving
|
|
||||||
// a ResourceProvisioner. This should not be used directly.
|
|
||||||
type ResourceProvisionerServer struct {
|
|
||||||
Broker *plugin.MuxBroker
|
|
||||||
Provisioner terraform.ResourceProvisioner
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ResourceProvisionerServer) Apply(
|
|
||||||
args *ResourceProvisionerApplyArgs,
|
|
||||||
result *ResourceProvisionerApplyResponse) error {
|
|
||||||
conn, err := s.Broker.Dial(args.OutputId)
|
|
||||||
if err != nil {
|
|
||||||
*result = ResourceProvisionerApplyResponse{
|
|
||||||
Error: plugin.NewBasicError(err),
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
client := rpc.NewClient(conn)
|
|
||||||
defer client.Close()
|
|
||||||
|
|
||||||
output := &UIOutput{Client: client}
|
|
||||||
|
|
||||||
err = s.Provisioner.Apply(output, args.State, args.Config)
|
|
||||||
*result = ResourceProvisionerApplyResponse{
|
|
||||||
Error: plugin.NewBasicError(err),
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ResourceProvisionerServer) Validate(
|
|
||||||
args *ResourceProvisionerValidateArgs,
|
|
||||||
reply *ResourceProvisionerValidateResponse) error {
|
|
||||||
warns, errs := s.Provisioner.Validate(args.Config)
|
|
||||||
berrs := make([]*plugin.BasicError, len(errs))
|
|
||||||
for i, err := range errs {
|
|
||||||
berrs[i] = plugin.NewBasicError(err)
|
|
||||||
}
|
|
||||||
*reply = ResourceProvisionerValidateResponse{
|
|
||||||
Warnings: warns,
|
|
||||||
Errors: berrs,
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ResourceProvisionerServer) Stop(
|
|
||||||
_ interface{},
|
|
||||||
reply *ResourceProvisionerStopResponse) error {
|
|
||||||
err := s.Provisioner.Stop()
|
|
||||||
*reply = ResourceProvisionerStopResponse{
|
|
||||||
Error: plugin.NewBasicError(err),
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,248 +0,0 @@
|
||||||
package plugin
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"reflect"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/hashicorp/go-plugin"
|
|
||||||
"github.com/hashicorp/terraform/internal/legacy/terraform"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestResourceProvisioner_impl(t *testing.T) {
|
|
||||||
var _ plugin.Plugin = new(ResourceProvisionerPlugin)
|
|
||||||
var _ terraform.ResourceProvisioner = new(ResourceProvisioner)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestResourceProvisioner_stop(t *testing.T) {
|
|
||||||
// Create a mock provider
|
|
||||||
p := new(terraform.MockResourceProvisioner)
|
|
||||||
client, _ := plugin.TestPluginRPCConn(t, legacyPluginMap(&ServeOpts{
|
|
||||||
ProvisionerFunc: testProvisionerFixed(p),
|
|
||||||
}), nil)
|
|
||||||
defer client.Close()
|
|
||||||
|
|
||||||
// Request the provider
|
|
||||||
raw, err := client.Dispense(ProvisionerPluginName)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
provider := raw.(terraform.ResourceProvisioner)
|
|
||||||
|
|
||||||
// Stop
|
|
||||||
e := provider.Stop()
|
|
||||||
if !p.StopCalled {
|
|
||||||
t.Fatal("stop should be called")
|
|
||||||
}
|
|
||||||
if e != nil {
|
|
||||||
t.Fatalf("bad: %#v", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestResourceProvisioner_stopErrors(t *testing.T) {
|
|
||||||
p := new(terraform.MockResourceProvisioner)
|
|
||||||
p.StopReturnError = errors.New("foo")
|
|
||||||
|
|
||||||
// Create a mock provider
|
|
||||||
client, _ := plugin.TestPluginRPCConn(t, legacyPluginMap(&ServeOpts{
|
|
||||||
ProvisionerFunc: testProvisionerFixed(p),
|
|
||||||
}), nil)
|
|
||||||
defer client.Close()
|
|
||||||
|
|
||||||
// Request the provider
|
|
||||||
raw, err := client.Dispense(ProvisionerPluginName)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
provider := raw.(terraform.ResourceProvisioner)
|
|
||||||
|
|
||||||
// Stop
|
|
||||||
e := provider.Stop()
|
|
||||||
if !p.StopCalled {
|
|
||||||
t.Fatal("stop should be called")
|
|
||||||
}
|
|
||||||
if e == nil {
|
|
||||||
t.Fatal("should have error")
|
|
||||||
}
|
|
||||||
if e.Error() != "foo" {
|
|
||||||
t.Fatalf("bad: %s", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestResourceProvisioner_apply(t *testing.T) {
|
|
||||||
// Create a mock provider
|
|
||||||
p := new(terraform.MockResourceProvisioner)
|
|
||||||
client, _ := plugin.TestPluginRPCConn(t, legacyPluginMap(&ServeOpts{
|
|
||||||
ProvisionerFunc: testProvisionerFixed(p),
|
|
||||||
}), nil)
|
|
||||||
defer client.Close()
|
|
||||||
|
|
||||||
// Request the provider
|
|
||||||
raw, err := client.Dispense(ProvisionerPluginName)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
provisioner := raw.(terraform.ResourceProvisioner)
|
|
||||||
|
|
||||||
// Apply
|
|
||||||
output := &terraform.MockUIOutput{}
|
|
||||||
state := &terraform.InstanceState{}
|
|
||||||
conf := &terraform.ResourceConfig{}
|
|
||||||
err = provisioner.Apply(output, state, conf)
|
|
||||||
if !p.ApplyCalled {
|
|
||||||
t.Fatal("apply should be called")
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(p.ApplyConfig, conf) {
|
|
||||||
t.Fatalf("bad: %#v", p.ApplyConfig)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("bad: %#v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestResourceProvisioner_validate(t *testing.T) {
|
|
||||||
// Create a mock provider
|
|
||||||
p := new(terraform.MockResourceProvisioner)
|
|
||||||
client, _ := plugin.TestPluginRPCConn(t, legacyPluginMap(&ServeOpts{
|
|
||||||
ProvisionerFunc: testProvisionerFixed(p),
|
|
||||||
}), nil)
|
|
||||||
defer client.Close()
|
|
||||||
|
|
||||||
// Request the provider
|
|
||||||
raw, err := client.Dispense(ProvisionerPluginName)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
provisioner := raw.(terraform.ResourceProvisioner)
|
|
||||||
|
|
||||||
// Configure
|
|
||||||
config := &terraform.ResourceConfig{
|
|
||||||
Raw: map[string]interface{}{"foo": "bar"},
|
|
||||||
}
|
|
||||||
w, e := provisioner.Validate(config)
|
|
||||||
if !p.ValidateCalled {
|
|
||||||
t.Fatal("configure should be called")
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(p.ValidateConfig, config) {
|
|
||||||
t.Fatalf("bad: %#v", p.ValidateConfig)
|
|
||||||
}
|
|
||||||
if w != nil {
|
|
||||||
t.Fatalf("bad: %#v", w)
|
|
||||||
}
|
|
||||||
if e != nil {
|
|
||||||
t.Fatalf("bad: %#v", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestResourceProvisioner_validate_errors(t *testing.T) {
|
|
||||||
// Create a mock provider
|
|
||||||
p := new(terraform.MockResourceProvisioner)
|
|
||||||
client, _ := plugin.TestPluginRPCConn(t, legacyPluginMap(&ServeOpts{
|
|
||||||
ProvisionerFunc: testProvisionerFixed(p),
|
|
||||||
}), nil)
|
|
||||||
defer client.Close()
|
|
||||||
|
|
||||||
// Request the provider
|
|
||||||
raw, err := client.Dispense(ProvisionerPluginName)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
provisioner := raw.(terraform.ResourceProvisioner)
|
|
||||||
|
|
||||||
p.ValidateReturnErrors = []error{errors.New("foo")}
|
|
||||||
|
|
||||||
// Configure
|
|
||||||
config := &terraform.ResourceConfig{
|
|
||||||
Raw: map[string]interface{}{"foo": "bar"},
|
|
||||||
}
|
|
||||||
w, e := provisioner.Validate(config)
|
|
||||||
if !p.ValidateCalled {
|
|
||||||
t.Fatal("configure should be called")
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(p.ValidateConfig, config) {
|
|
||||||
t.Fatalf("bad: %#v", p.ValidateConfig)
|
|
||||||
}
|
|
||||||
if w != nil {
|
|
||||||
t.Fatalf("bad: %#v", w)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(e) != 1 {
|
|
||||||
t.Fatalf("bad: %#v", e)
|
|
||||||
}
|
|
||||||
if e[0].Error() != "foo" {
|
|
||||||
t.Fatalf("bad: %#v", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestResourceProvisioner_validate_warns(t *testing.T) {
|
|
||||||
// Create a mock provider
|
|
||||||
p := new(terraform.MockResourceProvisioner)
|
|
||||||
client, _ := plugin.TestPluginRPCConn(t, legacyPluginMap(&ServeOpts{
|
|
||||||
ProvisionerFunc: testProvisionerFixed(p),
|
|
||||||
}), nil)
|
|
||||||
defer client.Close()
|
|
||||||
|
|
||||||
// Request the provider
|
|
||||||
raw, err := client.Dispense(ProvisionerPluginName)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
provisioner := raw.(terraform.ResourceProvisioner)
|
|
||||||
|
|
||||||
p.ValidateReturnWarns = []string{"foo"}
|
|
||||||
|
|
||||||
// Configure
|
|
||||||
config := &terraform.ResourceConfig{
|
|
||||||
Raw: map[string]interface{}{"foo": "bar"},
|
|
||||||
}
|
|
||||||
w, e := provisioner.Validate(config)
|
|
||||||
if !p.ValidateCalled {
|
|
||||||
t.Fatal("configure should be called")
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(p.ValidateConfig, config) {
|
|
||||||
t.Fatalf("bad: %#v", p.ValidateConfig)
|
|
||||||
}
|
|
||||||
if e != nil {
|
|
||||||
t.Fatalf("bad: %#v", e)
|
|
||||||
}
|
|
||||||
|
|
||||||
expected := []string{"foo"}
|
|
||||||
if !reflect.DeepEqual(w, expected) {
|
|
||||||
t.Fatalf("bad: %#v", w)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestResourceProvisioner_close(t *testing.T) {
|
|
||||||
// Create a mock provider
|
|
||||||
p := new(terraform.MockResourceProvisioner)
|
|
||||||
client, _ := plugin.TestPluginRPCConn(t, legacyPluginMap(&ServeOpts{
|
|
||||||
ProvisionerFunc: testProvisionerFixed(p),
|
|
||||||
}), nil)
|
|
||||||
defer client.Close()
|
|
||||||
|
|
||||||
// Request the provider
|
|
||||||
raw, err := client.Dispense(ProvisionerPluginName)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
provisioner := raw.(terraform.ResourceProvisioner)
|
|
||||||
|
|
||||||
pCloser, ok := raw.(terraform.ResourceProvisionerCloser)
|
|
||||||
if !ok {
|
|
||||||
t.Fatal("should be a ResourceProvisionerCloser")
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := pCloser.Close(); err != nil {
|
|
||||||
t.Fatalf("failed to close provisioner: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// The connection should be closed now, so if we to make a
|
|
||||||
// new call we should get an error.
|
|
||||||
o := &terraform.MockUIOutput{}
|
|
||||||
s := &terraform.InstanceState{}
|
|
||||||
c := &terraform.ResourceConfig{}
|
|
||||||
err = provisioner.Apply(o, s, c)
|
|
||||||
if err == nil {
|
|
||||||
t.Fatal("should have error")
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,8 +2,6 @@ package plugin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hashicorp/go-plugin"
|
"github.com/hashicorp/go-plugin"
|
||||||
grpcplugin "github.com/hashicorp/terraform/internal/legacy/helper/plugin"
|
|
||||||
"github.com/hashicorp/terraform/internal/legacy/terraform"
|
|
||||||
proto "github.com/hashicorp/terraform/internal/tfplugin5"
|
proto "github.com/hashicorp/terraform/internal/tfplugin5"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -35,16 +33,11 @@ var Handshake = plugin.HandshakeConfig{
|
||||||
MagicCookieValue: "d602bf8f470bc67ca7faa0386276bbdd4330efaf76d1a219cb4d6991ca9872b2",
|
MagicCookieValue: "d602bf8f470bc67ca7faa0386276bbdd4330efaf76d1a219cb4d6991ca9872b2",
|
||||||
}
|
}
|
||||||
|
|
||||||
type ProviderFunc func() terraform.ResourceProvider
|
|
||||||
type ProvisionerFunc func() terraform.ResourceProvisioner
|
|
||||||
type GRPCProviderFunc func() proto.ProviderServer
|
type GRPCProviderFunc func() proto.ProviderServer
|
||||||
type GRPCProvisionerFunc func() proto.ProvisionerServer
|
type GRPCProvisionerFunc func() proto.ProvisionerServer
|
||||||
|
|
||||||
// ServeOpts are the configurations to serve a plugin.
|
// ServeOpts are the configurations to serve a plugin.
|
||||||
type ServeOpts struct {
|
type ServeOpts struct {
|
||||||
ProviderFunc ProviderFunc
|
|
||||||
ProvisionerFunc ProvisionerFunc
|
|
||||||
|
|
||||||
// Wrapped versions of the above plugins will automatically shimmed and
|
// Wrapped versions of the above plugins will automatically shimmed and
|
||||||
// added to the GRPC functions when possible.
|
// added to the GRPC functions when possible.
|
||||||
GRPCProviderFunc GRPCProviderFunc
|
GRPCProviderFunc GRPCProviderFunc
|
||||||
|
@ -54,27 +47,6 @@ type ServeOpts struct {
|
||||||
// Serve serves a plugin. This function never returns and should be the final
|
// Serve serves a plugin. This function never returns and should be the final
|
||||||
// function called in the main function of the plugin.
|
// function called in the main function of the plugin.
|
||||||
func Serve(opts *ServeOpts) {
|
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{
|
plugin.Serve(&plugin.ServeConfig{
|
||||||
HandshakeConfig: Handshake,
|
HandshakeConfig: Handshake,
|
||||||
VersionedPlugins: pluginSet(opts),
|
VersionedPlugins: pluginSet(opts),
|
||||||
|
@ -82,26 +54,8 @@ func Serve(opts *ServeOpts) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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{
|
|
||||||
ResourceProvider: opts.ProviderFunc,
|
|
||||||
},
|
|
||||||
"provisioner": &ResourceProvisionerPlugin{
|
|
||||||
ResourceProvisioner: opts.ProvisionerFunc,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func pluginSet(opts *ServeOpts) map[int]plugin.PluginSet {
|
func pluginSet(opts *ServeOpts) map[int]plugin.PluginSet {
|
||||||
// Set the legacy netrpc plugins at version 4.
|
plugins := map[int]plugin.PluginSet{}
|
||||||
// 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
|
// add the new protocol versions if they're configured
|
||||||
if opts.GRPCProviderFunc != nil || opts.GRPCProvisionerFunc != nil {
|
if opts.GRPCProviderFunc != nil || opts.GRPCProvisionerFunc != nil {
|
||||||
|
|
Loading…
Reference in New Issue