diff --git a/builtin/providers/terraform/flatten.go b/builtin/providers/terraform/flatten.go deleted file mode 100644 index 4766a4f5e..000000000 --- a/builtin/providers/terraform/flatten.go +++ /dev/null @@ -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)) - } -} diff --git a/builtin/providers/terraform/provider.go b/builtin/providers/terraform/provider.go index 605362e3d..e33f14a71 100644 --- a/builtin/providers/terraform/provider.go +++ b/builtin/providers/terraform/provider.go @@ -17,7 +17,7 @@ type Provider struct { } // NewProvider returns a new terraform provider -func NewProvider() *Provider { +func NewProvider() providers.Interface { return &Provider{} } diff --git a/builtin/providers/terraform/provider_test.go b/builtin/providers/terraform/provider_test.go index 2a3a2bfe9..fecf720d2 100644 --- a/builtin/providers/terraform/provider_test.go +++ b/builtin/providers/terraform/provider_test.go @@ -1,29 +1,10 @@ package terraform import ( - "testing" - - "github.com/hashicorp/terraform/providers" - backendInit "github.com/hashicorp/terraform/backend/init" ) -var testAccProviders map[string]*Provider -var testAccProvider *Provider - func init() { // Initialize the backends 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) { } diff --git a/plugin/plugin.go b/plugin/plugin.go index e4fb57761..07a3000c0 100644 --- a/plugin/plugin.go +++ b/plugin/plugin.go @@ -4,8 +4,6 @@ import ( "github.com/hashicorp/go-plugin" ) -// See serve.go for serving plugins - var VersionedPlugins = map[int]plugin.PluginSet{ 5: { "provider": &GRPCProviderPlugin{}, diff --git a/plugin/plugin_test.go b/plugin/plugin_test.go deleted file mode 100644 index ddcde4c6e..000000000 --- a/plugin/plugin_test.go +++ /dev/null @@ -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 - } -} diff --git a/plugin/resource_provider.go b/plugin/resource_provider.go deleted file mode 100644 index 3ffe45f73..000000000 --- a/plugin/resource_provider.go +++ /dev/null @@ -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 -} diff --git a/plugin/resource_provider_test.go b/plugin/resource_provider_test.go deleted file mode 100644 index 36e96f59c..000000000 --- a/plugin/resource_provider_test.go +++ /dev/null @@ -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") - } -} diff --git a/plugin/resource_provisioner.go b/plugin/resource_provisioner.go deleted file mode 100644 index 2dfc8d1a6..000000000 --- a/plugin/resource_provisioner.go +++ /dev/null @@ -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 -} diff --git a/plugin/resource_provisioner_test.go b/plugin/resource_provisioner_test.go deleted file mode 100644 index bf00886e4..000000000 --- a/plugin/resource_provisioner_test.go +++ /dev/null @@ -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") - } -} diff --git a/plugin/serve.go b/plugin/serve.go index 3414eaa23..27d3c9e6d 100644 --- a/plugin/serve.go +++ b/plugin/serve.go @@ -2,8 +2,6 @@ package plugin import ( "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" ) @@ -35,16 +33,11 @@ var Handshake = plugin.HandshakeConfig{ MagicCookieValue: "d602bf8f470bc67ca7faa0386276bbdd4330efaf76d1a219cb4d6991ca9872b2", } -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 @@ -54,27 +47,6 @@ type ServeOpts struct { // 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, 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 { - // 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), - } + plugins := map[int]plugin.PluginSet{} // add the new protocol versions if they're configured if opts.GRPCProviderFunc != nil || opts.GRPCProvisionerFunc != nil {