rpc: Diff implementation

This commit is contained in:
Mitchell Hashimoto 2014-06-06 00:48:32 -07:00
parent 0561edc2fd
commit 02a3603a9a
5 changed files with 119 additions and 30 deletions

View File

@ -13,9 +13,28 @@ type ResourceProvider struct {
Name string
}
func (p *ResourceProvider) Configure(c map[string]interface{}) ([]string, error) {
func (p *ResourceProvider) Configure(c map[string]interface{}) error {
var resp ResourceProviderConfigureResponse
err := p.Client.Call(p.Name+".Configure", c, &resp)
if err != nil {
return err
}
if resp.Error != nil {
err = resp.Error
}
return err
}
func (p *ResourceProvider) Diff(
s *terraform.ResourceState,
c map[string]interface{}) (*terraform.ResourceDiff, error) {
var resp ResourceProviderDiffResponse
args := &ResourceProviderDiffArgs{
State: s,
Config: c,
}
err := p.Client.Call(p.Name+".Diff", args, &resp)
if err != nil {
return nil, err
}
@ -23,7 +42,7 @@ func (p *ResourceProvider) Configure(c map[string]interface{}) ([]string, error)
err = resp.Error
}
return resp.Warnings, err
return resp.Diff, err
}
func (p *ResourceProvider) Resources() []terraform.ResourceType {
@ -45,17 +64,36 @@ type ResourceProviderServer struct {
}
type ResourceProviderConfigureResponse struct {
Warnings []string
Error *BasicError
Error *BasicError
}
type ResourceProviderDiffArgs struct {
State *terraform.ResourceState
Config map[string]interface{}
}
type ResourceProviderDiffResponse struct {
Diff *terraform.ResourceDiff
Error *BasicError
}
func (s *ResourceProviderServer) Configure(
config map[string]interface{},
reply *ResourceProviderConfigureResponse) error {
warnings, err := s.Provider.Configure(config)
err := s.Provider.Configure(config)
*reply = ResourceProviderConfigureResponse{
Warnings: warnings,
Error: NewBasicError(err),
Error: NewBasicError(err),
}
return nil
}
func (s *ResourceProviderServer) Diff(
args *ResourceProviderDiffArgs,
result *ResourceProviderDiffResponse) error {
diff, err := s.Provider.Diff(args.State, args.Config)
*result = ResourceProviderDiffResponse{
Diff: diff,
Error: NewBasicError(err),
}
return nil
}

View File

@ -19,16 +19,13 @@ func TestResourceProvider_configure(t *testing.T) {
// Configure
config := map[string]interface{}{"foo": "bar"}
w, e := provider.Configure(config)
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 w != nil {
t.Fatalf("bad: %#v", w)
}
if e != nil {
t.Fatalf("bad: %#v", e)
}
@ -47,16 +44,13 @@ func TestResourceProvider_configure_errors(t *testing.T) {
// Configure
config := map[string]interface{}{"foo": "bar"}
w, e := provider.Configure(config)
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 w != nil {
t.Fatalf("bad: %#v", w)
}
if e == nil {
t.Fatal("should have error")
}
@ -74,28 +68,85 @@ func TestResourceProvider_configure_warnings(t *testing.T) {
}
provider := &ResourceProvider{Client: client, Name: name}
p.ConfigureReturnWarnings = []string{"foo", "bar"}
// Configure
config := map[string]interface{}{"foo": "bar"}
w, e := provider.Configure(config)
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 w == nil {
t.Fatal("should have warnings")
}
if !reflect.DeepEqual(w, []string{"foo", "bar"}) {
t.Fatalf("bad: %#v", w)
}
if e != nil {
t.Fatalf("bad: %#v", e)
}
}
func TestResourceProvider_diff(t *testing.T) {
p := new(terraform.MockResourceProvider)
client, server := testClientServer(t)
name, err := Register(server, p)
if err != nil {
t.Fatalf("err: %s", err)
}
provider := &ResourceProvider{Client: client, Name: name}
p.DiffReturn = &terraform.ResourceDiff{
Attributes: map[string]*terraform.ResourceAttrDiff{
"foo": &terraform.ResourceAttrDiff{
Old: "",
New: "bar",
},
},
}
// Diff
state := &terraform.ResourceState{}
config := map[string]interface{}{"foo": "bar"}
diff, err := provider.Diff(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)
client, server := testClientServer(t)
name, err := Register(server, p)
if err != nil {
t.Fatalf("err: %s", err)
}
provider := &ResourceProvider{Client: client, Name: name}
p.DiffReturnError = errors.New("foo")
// Diff
state := &terraform.ResourceState{}
config := map[string]interface{}{"foo": "bar"}
diff, err := provider.Diff(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_resources(t *testing.T) {
p := new(terraform.MockResourceProvider)
client, server := testClientServer(t)

View File

@ -30,7 +30,7 @@ type ResourceProvider interface {
// a diff.
Diff(
*ResourceState,
map[string]interface{}) (ResourceDiff, error)
map[string]interface{}) (*ResourceDiff, error)
}
// ResourceType is a type of resource that a resource provider can manage.

View File

@ -12,8 +12,8 @@ type MockResourceProvider struct {
DiffCalled bool
DiffState *ResourceState
DiffDesired map[string]interface{}
DiffFn func(*ResourceState, map[string]interface{}) (ResourceDiff, error)
DiffReturn ResourceDiff
DiffFn func(*ResourceState, map[string]interface{}) (*ResourceDiff, error)
DiffReturn *ResourceDiff
DiffReturnError error
ResourcesCalled bool
ResourcesReturn []ResourceType
@ -27,7 +27,7 @@ func (p *MockResourceProvider) Configure(c map[string]interface{}) error {
func (p *MockResourceProvider) Diff(
state *ResourceState,
desired map[string]interface{}) (ResourceDiff, error) {
desired map[string]interface{}) (*ResourceDiff, error) {
p.DiffCalled = true
p.DiffState = state
p.DiffDesired = desired

View File

@ -261,7 +261,7 @@ func testProviderFunc(n string, rs []string) ResourceProviderFactory {
return func() (ResourceProvider, error) {
diffFn := func(
_ *ResourceState,
c map[string]interface{}) (ResourceDiff, error) {
c map[string]interface{}) (*ResourceDiff, error) {
var diff ResourceDiff
diff.Attributes = make(map[string]*ResourceAttrDiff)
for k, v := range c {
@ -290,7 +290,7 @@ func testProviderFunc(n string, rs []string) ResourceProviderFactory {
diff.Attributes[k] = attrDiff
}
return diff, nil
return &diff, nil
}
result := &MockResourceProvider{