func (m schemaMap) validateMap( k string, raw interface{}, schema *Schema, c *terraform.ResourceConfig) ([]string, []error) { // We use reflection to verify the slice because you can't // case to []interface{} unless the slice is exactly that type. rawV := reflect.ValueOf(raw) switch rawV.Kind() { case reflect.String: // If raw and reified are equal, this is a string and should // be rejected. reified, reifiedOk := c.Get(k) log.Printf("[jen20] reified: %s", spew.Sdump(reified)) log.Printf("[jen20] raw: %s", spew.Sdump(raw)) if reifiedOk && raw == reified && !c.IsComputed(k) { return nil, []error{fmt.Errorf("%s: should be a map", k)} } // Otherwise it's likely raw is an interpolation. return nil, nil case reflect.Map: case reflect.Slice: default: return nil, []error{fmt.Errorf("%s: should be a map", k)} } // If it is not a slice, it is valid if rawV.Kind() != reflect.Slice { return nil, nil } // It is a slice, verify that all the elements are maps raws := make([]interface{}, rawV.Len()) for i, _ := range raws { raws[i] = rawV.Index(i).Interface() } for _, raw := range raws { v := reflect.ValueOf(raw) if v.Kind() != reflect.Map { return nil, []error{fmt.Errorf( "%s: should be a map", k)} } } if schema.ValidateFunc != nil { validatableMap := make(map[string]interface{}) for _, raw := range raws { for k, v := range raw.(map[string]interface{}) { validatableMap[k] = v } } return schema.ValidateFunc(validatableMap, k) } return nil, nil }
func (m schemaMap) validatePrimitive( k string, raw interface{}, schema *Schema, c *terraform.ResourceConfig) ([]string, []error) { if c.IsComputed(k) { // If the key is being computed, then it is not an error return nil, nil } var decoded interface{} switch schema.Type { case TypeBool: // Verify that we can parse this as the correct type var n bool if err := mapstructure.WeakDecode(raw, &n); err != nil { return nil, []error{err} } decoded = n case TypeInt: // Verify that we can parse this as an int var n int if err := mapstructure.WeakDecode(raw, &n); err != nil { return nil, []error{err} } decoded = n case TypeFloat: // Verify that we can parse this as an int var n float64 if err := mapstructure.WeakDecode(raw, &n); err != nil { return nil, []error{err} } decoded = n case TypeString: // Verify that we can parse this as a string var n string if err := mapstructure.WeakDecode(raw, &n); err != nil { return nil, []error{err} } decoded = n default: panic(fmt.Sprintf("Unknown validation type: %#v", schema.Type)) } if schema.ValidateFunc != nil { return schema.ValidateFunc(decoded, k) } return nil, nil }
func (m schemaMap) validatePrimitive( k string, raw interface{}, schema *Schema, c *terraform.ResourceConfig) ([]string, []error) { if c.IsComputed(k) { // If the key is being computed, then it is not an error return nil, nil } switch schema.Type { case TypeSet: fallthrough case TypeList: return m.validateList(k, raw, schema, c) case TypeMap: return m.validateMap(k, raw, schema, c) case TypeBool: // Verify that we can parse this as the correct type var n bool if err := mapstructure.WeakDecode(raw, &n); err != nil { return nil, []error{err} } case TypeInt: // Verify that we can parse this as an int var n int if err := mapstructure.WeakDecode(raw, &n); err != nil { return nil, []error{err} } case TypeString: // Verify that we can parse this as a string var n string if err := mapstructure.WeakDecode(raw, &n); err != nil { return nil, []error{err} } default: panic(fmt.Sprintf("Unknown validation type: %#v", schema.Type)) } return nil, nil }
func (m schemaMap) validatePrimitive( k string, raw interface{}, schema *Schema, c *terraform.ResourceConfig) ([]string, []error) { // Catch if the user gave a complex type where a primitive was // expected, so we can return a friendly error message that // doesn't contain Go type system terminology. switch reflect.ValueOf(raw).Type().Kind() { case reflect.Slice: return nil, []error{ fmt.Errorf("%s must be a single value, not a list", k), } case reflect.Map: return nil, []error{ fmt.Errorf("%s must be a single value, not a map", k), } default: // ok } if c.IsComputed(k) { // If the key is being computed, then it is not an error as // long as it's not a slice or map. return nil, nil } var decoded interface{} switch schema.Type { case TypeBool: // Verify that we can parse this as the correct type var n bool if err := mapstructure.WeakDecode(raw, &n); err != nil { return nil, []error{err} } decoded = n case TypeInt: // Verify that we can parse this as an int var n int if err := mapstructure.WeakDecode(raw, &n); err != nil { return nil, []error{err} } decoded = n case TypeFloat: // Verify that we can parse this as an int var n float64 if err := mapstructure.WeakDecode(raw, &n); err != nil { return nil, []error{err} } decoded = n case TypeString: // Verify that we can parse this as a string var n string if err := mapstructure.WeakDecode(raw, &n); err != nil { return nil, []error{err} } decoded = n default: panic(fmt.Sprintf("Unknown validation type: %#v", schema.Type)) } if schema.ValidateFunc != nil { return schema.ValidateFunc(decoded, k) } return nil, nil }