helper/schema: add support for StateFunc

This commit is contained in:
Mitchell Hashimoto 2014-08-22 08:45:54 -07:00
parent 7be2f1b091
commit d009ea800a
4 changed files with 85 additions and 4 deletions

View File

@ -28,6 +28,7 @@ const (
type getResult struct {
Value interface{}
Exists bool
Schema *Schema
}
var getResultEmpty getResult
@ -200,6 +201,10 @@ func (d *ResourceData) diffChange(k string) (interface{}, interface{}, bool) {
n.Value = nil
}
if n.Exists && n.Schema.StateFunc != nil {
n.Value = n.Schema.StateFunc(n.Value)
}
// Return the old, new, and whether there is a change
return o.Value, n.Value, !reflect.DeepEqual(o.Value, n.Value)
}
@ -248,7 +253,7 @@ func (d *ResourceData) getSet(
schema *Schema,
source getSource) getResult {
s := &Set{F: schema.Set}
result := getResult{Value: s}
result := getResult{Schema: schema, Value: s}
raw := d.getList(k, nil, schema, source)
if !raw.Exists {
if len(parts) > 0 {
@ -394,6 +399,7 @@ func (d *ResourceData) getMap(
return getResult{
Value: resultValue,
Exists: resultSet,
Schema: schema,
}
}
@ -429,6 +435,9 @@ func (d *ResourceData) getObject(
return getResult{
Value: result,
Exists: true,
Schema: &Schema{
Elem: schema,
},
}
}
@ -469,6 +478,7 @@ func (d *ResourceData) getList(
return getResult{
Value: result,
Exists: count.Exists,
Schema: schema,
}
}
@ -553,6 +563,7 @@ func (d *ResourceData) getPrimitive(
return getResult{
Value: resultValue,
Exists: resultSet,
Schema: schema,
}
}

View File

@ -1430,6 +1430,35 @@ func TestResourceDataState(t *testing.T) {
},
},
// Basic primitive with StateFunc set
{
Schema: map[string]*Schema{
"availability_zone": &Schema{
Type: TypeString,
Optional: true,
Computed: true,
StateFunc: func(interface{}) string { return "" },
},
},
State: nil,
Diff: &terraform.ResourceDiff{
Attributes: map[string]*terraform.ResourceAttrDiff{
"availability_zone": &terraform.ResourceAttrDiff{
Old: "",
New: "foo",
},
},
},
Result: &terraform.ResourceState{
Attributes: map[string]string{
"availability_zone": "foo",
},
},
},
// List
{
Schema: map[string]*Schema{

View File

@ -41,8 +41,14 @@ type Schema struct {
//
// If ForceNew is true, then a change in this resource necessitates
// the creation of a new resource.
Computed bool
ForceNew bool
//
// StateFunc is a function called to change the value of this before
// storing it in the state (and likewise before comparing for diffs).
// The use for this is for example with large strings, you may want
// to simply store the hash of it.
Computed bool
ForceNew bool
StateFunc SchemaStateFunc
// The following fields are only set for a TypeList or TypeSet Type.
//
@ -66,7 +72,11 @@ type Schema struct {
// SchemaSetFunc is a function that must return a unique ID for the given
// element. This unique ID is used to store the element in a hash.
type SchemaSetFunc func(a interface{}) int
type SchemaSetFunc func(interface{}) int
// SchemaStateFunc is a function used to convert some type to a string
// to be stored in the state.
type SchemaStateFunc func(interface{}) string
func (s *Schema) finalizeDiff(
d *terraform.ResourceAttrDiff) *terraform.ResourceAttrDiff {

View File

@ -76,6 +76,37 @@ func TestSchemaMap_Diff(t *testing.T) {
Err: false,
},
// String with StateFunc
{
Schema: map[string]*Schema{
"availability_zone": &Schema{
Type: TypeString,
Optional: true,
Computed: true,
StateFunc: func(a interface{}) string {
return a.(string) + "!"
},
},
},
State: nil,
Config: map[string]interface{}{
"availability_zone": "foo",
},
Diff: &terraform.ResourceDiff{
Attributes: map[string]*terraform.ResourceAttrDiff{
"availability_zone": &terraform.ResourceAttrDiff{
Old: "",
New: "foo!",
},
},
},
Err: false,
},
/*
* Int decode
*/