Skip to content

Commit 894187e

Browse files
committed
helper/schema: Resource.Refresh
1 parent 7db585c commit 894187e

5 files changed

Lines changed: 98 additions & 14 deletions

File tree

helper/schema/provider.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,15 @@ type Provider struct {
1717
ResourcesMap map[string]*Resource
1818

1919
ConfigureFunc ConfigureFunc
20+
21+
meta interface{}
2022
}
2123

2224
// ConfigureFunc is the function used to configure a Provider.
23-
type ConfigureFunc func(*ResourceData) error
25+
//
26+
// The interface{} value returned by this function is stored and passed into
27+
// the subsequent resources as the meta parameter.
28+
type ConfigureFunc func(*ResourceData) (interface{}, error)
2429

2530
// Validate validates the provider configuration against the schema.
2631
func (p *Provider) Validate(c *terraform.ResourceConfig) ([]string, []error) {
@@ -61,7 +66,13 @@ func (p *Provider) Configure(c *terraform.ResourceConfig) error {
6166
return err
6267
}
6368

64-
return p.ConfigureFunc(data)
69+
meta, err := p.ConfigureFunc(data)
70+
if err != nil {
71+
return err
72+
}
73+
74+
p.meta = meta
75+
return nil
6576
}
6677

6778
// Resources implementation of terraform.ResourceProvider interface.

helper/schema/provider_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,12 @@ func TestProviderConfigure(t *testing.T) {
3030
},
3131
},
3232

33-
ConfigureFunc: func(d *ResourceData) error {
33+
ConfigureFunc: func(d *ResourceData) (interface{}, error) {
3434
if d.Get("foo").(int) == 42 {
35-
return nil
35+
return nil, nil
3636
}
3737

38-
return fmt.Errorf("nope")
38+
return nil, fmt.Errorf("nope")
3939
},
4040
},
4141
Config: map[string]interface{}{
@@ -53,12 +53,12 @@ func TestProviderConfigure(t *testing.T) {
5353
},
5454
},
5555

56-
ConfigureFunc: func(d *ResourceData) error {
56+
ConfigureFunc: func(d *ResourceData) (interface{}, error) {
5757
if d.Get("foo").(int) == 42 {
58-
return nil
58+
return nil, nil
5959
}
6060

61-
return fmt.Errorf("nope")
61+
return nil, fmt.Errorf("nope")
6262
},
6363
},
6464
Config: map[string]interface{}{

helper/schema/resource.go

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,13 @@ import (
77
)
88

99
// The functions below are the CRUD function types for a Resource.
10-
type CreateFunc func(*ResourceData) error
11-
type ReadFunc func(*ResourceData) error
12-
type UpdateFunc func(*ResourceData) error
13-
type DeleteFunc func(*ResourceData) error
10+
//
11+
// The second parameter is the meta value sent to the resource when
12+
// different operations are called.
13+
type CreateFunc func(*ResourceData, interface{}) error
14+
type ReadFunc func(*ResourceData, interface{}) error
15+
type UpdateFunc func(*ResourceData, interface{}) error
16+
type DeleteFunc func(*ResourceData, interface{}) error
1417

1518
// Resource represents a thing in Terraform that has a set of configurable
1619
// attributes and generally also has a lifecycle (create, read, update,
@@ -41,6 +44,19 @@ func (r *Resource) Validate(c *terraform.ResourceConfig) ([]string, []error) {
4144
return schemaMap(r.Schema).Validate(c)
4245
}
4346

47+
// Refresh refreshes the state of the resource.
48+
func (r *Resource) Refresh(
49+
s *terraform.ResourceState,
50+
meta interface{}) (*terraform.ResourceState, error) {
51+
data, err := schemaMap(r.Schema).Data(s, nil)
52+
if err != nil {
53+
return nil, err
54+
}
55+
56+
err = r.Read(data, meta)
57+
return data.State(), err
58+
}
59+
4460
// InternalValidate should be called to validate the structure
4561
// of the resource.
4662
//

helper/schema/resource_data.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ type ResourceData struct {
1414
schema map[string]*Schema
1515
state *terraform.ResourceState
1616
diff *terraform.ResourceDiff
17-
setMap map[string]string
17+
18+
setMap map[string]string
19+
newState *terraform.ResourceState
1820
}
1921

2022
// Get returns the data for the given key, or nil if the key doesn't exist.
@@ -49,6 +51,15 @@ func (d *ResourceData) Set(key string, value interface{}) error {
4951
func (d *ResourceData) State() *terraform.ResourceState {
5052
var result terraform.ResourceState
5153
result.Attributes = d.stateObject("", d.schema)
54+
55+
if d.state != nil {
56+
result.ID = d.state.ID
57+
}
58+
59+
if d.newState != nil {
60+
result.ID = d.newState.ID
61+
}
62+
5263
return &result
5364
}
5465

@@ -335,7 +346,7 @@ func (d *ResourceData) stateList(
335346
count := countRaw.(int)
336347

337348
result := make(map[string]string)
338-
result[prefix + ".#"] = strconv.FormatInt(int64(count), 10)
349+
result[prefix+".#"] = strconv.FormatInt(int64(count), 10)
339350
for i := 0; i < count; i++ {
340351
key := fmt.Sprintf("%s.%d", prefix, i)
341352

helper/schema/resource_test.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
package schema
22

33
import (
4+
"fmt"
5+
"reflect"
46
"testing"
7+
8+
"github.com/hashicorp/terraform/terraform"
59
)
610

711
func TestResourceInternalValidate(t *testing.T) {
@@ -36,3 +40,45 @@ func TestResourceInternalValidate(t *testing.T) {
3640
}
3741
}
3842
}
43+
44+
func TestResourceRefresh(t *testing.T) {
45+
r := &Resource{
46+
Schema: map[string]*Schema{
47+
"foo": &Schema{
48+
Type: TypeInt,
49+
Optional: true,
50+
},
51+
},
52+
}
53+
54+
r.Read = func(d *ResourceData, m interface{}) error {
55+
if m != 42 {
56+
return fmt.Errorf("meta not passed")
57+
}
58+
59+
return d.Set("foo", d.Get("foo").(int)+1)
60+
}
61+
62+
s := &terraform.ResourceState{
63+
ID: "bar",
64+
Attributes: map[string]string{
65+
"foo": "12",
66+
},
67+
}
68+
69+
expected := &terraform.ResourceState{
70+
ID: "bar",
71+
Attributes: map[string]string{
72+
"foo": "13",
73+
},
74+
}
75+
76+
actual, err := r.Refresh(s, 42)
77+
if err != nil {
78+
t.Fatalf("err: %s", err)
79+
}
80+
81+
if !reflect.DeepEqual(actual, expected) {
82+
t.Fatalf("bad: %#v", actual)
83+
}
84+
}

0 commit comments

Comments
 (0)