helper/schema: Input support

This commit is contained in:
Mitchell Hashimoto 2014-09-29 10:25:43 -07:00
parent 2791badf01
commit 5aed997223
3 changed files with 112 additions and 0 deletions

View File

@ -87,6 +87,13 @@ func (p *Provider) SetMeta(v interface{}) {
p.meta = v p.meta = v
} }
// Input implementation of terraform.ResourceProvider interface.
func (p *Provider) Input(
input terraform.UIInput,
c *terraform.ResourceConfig) (*terraform.ResourceConfig, error) {
return schemaMap(p.Schema).Input(input, c)
}
// Validate implementation of terraform.ResourceProvider interface. // Validate implementation of terraform.ResourceProvider interface.
func (p *Provider) Validate(c *terraform.ResourceConfig) ([]string, []error) { func (p *Provider) Validate(c *terraform.ResourceConfig) ([]string, []error) {
return schemaMap(p.Schema).Validate(c) return schemaMap(p.Schema).Validate(c)

View File

@ -270,6 +270,42 @@ func (m schemaMap) Diff(
return result, nil return result, nil
} }
// Input implements the terraform.ResourceProvider method by asking
// for input for required configuration keys that don't have a value.
func (m schemaMap) Input(
input terraform.UIInput,
c *terraform.ResourceConfig) (*terraform.ResourceConfig, error) {
for k, v := range m {
// Skip things that don't require config, if that is even valid
// for a provider schema.
if !v.Required && !v.Optional {
continue
}
var value interface{}
var err error
switch v.Type {
case TypeBool:
fallthrough
case TypeInt:
fallthrough
case TypeString:
value, err = m.inputString(input, k, v)
default:
panic(fmt.Sprintf("Unknown type for input: %s", v.Type))
}
if err != nil {
return nil, fmt.Errorf(
"%s: %s", k, err)
}
c.Raw[k] = value
}
return c, nil
}
// Validate validates the configuration against this schema mapping. // Validate validates the configuration against this schema mapping.
func (m schemaMap) Validate(c *terraform.ResourceConfig) ([]string, []error) { func (m schemaMap) Validate(c *terraform.ResourceConfig) ([]string, []error) {
return m.validateObject("", m, c) return m.validateObject("", m, c)
@ -569,6 +605,18 @@ func (m schemaMap) diffString(
return nil return nil
} }
func (m schemaMap) inputString(
input terraform.UIInput,
k string,
schema *Schema) (interface{}, error) {
result, err := input.Input(&terraform.InputOpts{
Id: k,
Query: fmt.Sprintf("%s: ", k),
})
return result, err
}
func (m schemaMap) validate( func (m schemaMap) validate(
k string, k string,
schema *Schema, schema *Schema,

View File

@ -1035,6 +1035,63 @@ func TestSchemaMap_Diff(t *testing.T) {
} }
} }
func TestSchemaMap_Input(t *testing.T) {
cases := []struct {
Schema map[string]*Schema
Config map[string]interface{}
Input map[string]string
Result map[string]interface{}
Err bool
}{
/*
* String decode
*/
{
Schema: map[string]*Schema{
"availability_zone": &Schema{
Type: TypeString,
Optional: true,
},
},
Config: map[string]interface{}{
"availability_zone": "bar",
},
Input: map[string]string{
"availability_zone": "foo",
},
Result: map[string]interface{}{
"availability_zone": "foo",
},
Err: false,
},
}
for i, tc := range cases {
c, err := config.NewRawConfig(tc.Config)
if err != nil {
t.Fatalf("err: %s", err)
}
input := new(terraform.MockUIInput)
input.InputReturnMap = tc.Input
actual, err := schemaMap(tc.Schema).Input(
input, terraform.NewResourceConfig(c))
if (err != nil) != tc.Err {
t.Fatalf("#%d err: %s", i, err)
}
if !reflect.DeepEqual(tc.Result, actual.Raw) {
t.Fatalf("#%d: bad:\n\n%#v", i, actual.Raw)
}
}
}
func TestSchemaMap_InternalValidate(t *testing.T) { func TestSchemaMap_InternalValidate(t *testing.T) {
cases := []struct { cases := []struct {
In map[string]*Schema In map[string]*Schema