func (m schemaMap) validate( k string, schema *Schema, c *terraform.ResourceConfig) ([]string, []error) { raw, ok := c.Get(k) if !ok && schema.DefaultFunc != nil { // We have a dynamic default. Check if we have a value. var err error raw, err = schema.DefaultFunc() if err != nil { return nil, []error{fmt.Errorf( "%q, error loading default: %s", k, err)} } // We're okay as long as we had a value set ok = raw != nil } if !ok { if schema.Required { return nil, []error{fmt.Errorf( "%q: required field is not set", k)} } return nil, nil } if !schema.Required && !schema.Optional { // This is a computed-only field return nil, []error{fmt.Errorf( "%q: this field cannot be set", k)} } return m.validateType(k, raw, schema, c) }
func (m schemaMap) validateObject( k string, schema map[string]*Schema, c *terraform.ResourceConfig) ([]string, []error) { var ws []string var es []error for subK, s := range schema { key := subK if k != "" { key = fmt.Sprintf("%s.%s", k, subK) } ws2, es2 := m.validate(key, s, c) if len(ws2) > 0 { ws = append(ws, ws2...) } if len(es2) > 0 { es = append(es, es2...) } } // Detect any extra/unknown keys and report those as errors. raw, _ := c.Get(k) if m, ok := raw.(map[string]interface{}); ok { for subk, _ := range m { if _, ok := schema[subk]; !ok { es = append(es, fmt.Errorf( "%s: invalid or unknown key: %s", k, subk)) } } } return ws, es }
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) validateConflictingAttributes( k string, schema *Schema, c *terraform.ResourceConfig) error { if len(schema.ConflictsWith) == 0 { return nil } for _, conflicting_key := range schema.ConflictsWith { if value, ok := c.Get(conflicting_key); ok { return fmt.Errorf( "%q: conflicts with %s (%#v)", k, conflicting_key, value) } } return nil }
func (m schemaMap) validate( k string, schema *Schema, c *terraform.ResourceConfig) ([]string, []error) { raw, ok := c.Get(k) if !ok { if schema.Required { return nil, []error{fmt.Errorf( "%s: required field is not set", k)} } return nil, nil } if !schema.Required && !schema.Optional { // This is a computed-only field return nil, []error{fmt.Errorf( "%s: this field cannot be set", k)} } return m.validatePrimitive(k, raw, schema, c) }