diff options
Diffstat (limited to 'vendor/github.com/hashicorp/terraform/helper/schema/schema.go')
-rw-r--r-- | vendor/github.com/hashicorp/terraform/helper/schema/schema.go | 75 |
1 files changed, 67 insertions, 8 deletions
diff --git a/vendor/github.com/hashicorp/terraform/helper/schema/schema.go b/vendor/github.com/hashicorp/terraform/helper/schema/schema.go index 6a3c15a..bcc8e4b 100644 --- a/vendor/github.com/hashicorp/terraform/helper/schema/schema.go +++ b/vendor/github.com/hashicorp/terraform/helper/schema/schema.go | |||
@@ -22,7 +22,7 @@ import ( | |||
22 | "strings" | 22 | "strings" |
23 | "sync" | 23 | "sync" |
24 | 24 | ||
25 | "github.com/hashicorp/terraform/config" | 25 | "github.com/hashicorp/terraform/config/hcl2shim" |
26 | "github.com/hashicorp/terraform/terraform" | 26 | "github.com/hashicorp/terraform/terraform" |
27 | "github.com/mitchellh/copystructure" | 27 | "github.com/mitchellh/copystructure" |
28 | "github.com/mitchellh/mapstructure" | 28 | "github.com/mitchellh/mapstructure" |
@@ -1365,10 +1365,15 @@ func (m schemaMap) validate( | |||
1365 | "%q: this field cannot be set", k)} | 1365 | "%q: this field cannot be set", k)} |
1366 | } | 1366 | } |
1367 | 1367 | ||
1368 | if raw == config.UnknownVariableValue { | 1368 | // If the value is unknown then we can't validate it yet. |
1369 | // If the value is unknown then we can't validate it yet. | 1369 | // In particular, this avoids spurious type errors where downstream |
1370 | // In particular, this avoids spurious type errors where downstream | 1370 | // validation code sees UnknownVariableValue as being just a string. |
1371 | // validation code sees UnknownVariableValue as being just a string. | 1371 | // The SDK has to allow the unknown value through initially, so that |
1372 | // Required fields set via an interpolated value are accepted. | ||
1373 | if !isWhollyKnown(raw) { | ||
1374 | if schema.Deprecated != "" { | ||
1375 | return []string{fmt.Sprintf("%q: [DEPRECATED] %s", k, schema.Deprecated)}, nil | ||
1376 | } | ||
1372 | return nil, nil | 1377 | return nil, nil |
1373 | } | 1378 | } |
1374 | 1379 | ||
@@ -1380,6 +1385,28 @@ func (m schemaMap) validate( | |||
1380 | return m.validateType(k, raw, schema, c) | 1385 | return m.validateType(k, raw, schema, c) |
1381 | } | 1386 | } |
1382 | 1387 | ||
1388 | // isWhollyKnown returns false if the argument contains an UnknownVariableValue | ||
1389 | func isWhollyKnown(raw interface{}) bool { | ||
1390 | switch raw := raw.(type) { | ||
1391 | case string: | ||
1392 | if raw == hcl2shim.UnknownVariableValue { | ||
1393 | return false | ||
1394 | } | ||
1395 | case []interface{}: | ||
1396 | for _, v := range raw { | ||
1397 | if !isWhollyKnown(v) { | ||
1398 | return false | ||
1399 | } | ||
1400 | } | ||
1401 | case map[string]interface{}: | ||
1402 | for _, v := range raw { | ||
1403 | if !isWhollyKnown(v) { | ||
1404 | return false | ||
1405 | } | ||
1406 | } | ||
1407 | } | ||
1408 | return true | ||
1409 | } | ||
1383 | func (m schemaMap) validateConflictingAttributes( | 1410 | func (m schemaMap) validateConflictingAttributes( |
1384 | k string, | 1411 | k string, |
1385 | schema *Schema, | 1412 | schema *Schema, |
@@ -1391,7 +1418,7 @@ func (m schemaMap) validateConflictingAttributes( | |||
1391 | 1418 | ||
1392 | for _, conflictingKey := range schema.ConflictsWith { | 1419 | for _, conflictingKey := range schema.ConflictsWith { |
1393 | if raw, ok := c.Get(conflictingKey); ok { | 1420 | if raw, ok := c.Get(conflictingKey); ok { |
1394 | if raw == config.UnknownVariableValue { | 1421 | if raw == hcl2shim.UnknownVariableValue { |
1395 | // An unknown value might become unset (null) once known, so | 1422 | // An unknown value might become unset (null) once known, so |
1396 | // we must defer validation until it's known. | 1423 | // we must defer validation until it's known. |
1397 | continue | 1424 | continue |
@@ -1411,11 +1438,16 @@ func (m schemaMap) validateList( | |||
1411 | c *terraform.ResourceConfig) ([]string, []error) { | 1438 | c *terraform.ResourceConfig) ([]string, []error) { |
1412 | // first check if the list is wholly unknown | 1439 | // first check if the list is wholly unknown |
1413 | if s, ok := raw.(string); ok { | 1440 | if s, ok := raw.(string); ok { |
1414 | if s == config.UnknownVariableValue { | 1441 | if s == hcl2shim.UnknownVariableValue { |
1415 | return nil, nil | 1442 | return nil, nil |
1416 | } | 1443 | } |
1417 | } | 1444 | } |
1418 | 1445 | ||
1446 | // schemaMap can't validate nil | ||
1447 | if raw == nil { | ||
1448 | return nil, nil | ||
1449 | } | ||
1450 | |||
1419 | // We use reflection to verify the slice because you can't | 1451 | // We use reflection to verify the slice because you can't |
1420 | // case to []interface{} unless the slice is exactly that type. | 1452 | // case to []interface{} unless the slice is exactly that type. |
1421 | rawV := reflect.ValueOf(raw) | 1453 | rawV := reflect.ValueOf(raw) |
@@ -1432,6 +1464,15 @@ func (m schemaMap) validateList( | |||
1432 | "%s: should be a list", k)} | 1464 | "%s: should be a list", k)} |
1433 | } | 1465 | } |
1434 | 1466 | ||
1467 | // We can't validate list length if this came from a dynamic block. | ||
1468 | // Since there's no way to determine if something was from a dynamic block | ||
1469 | // at this point, we're going to skip validation in the new protocol if | ||
1470 | // there are any unknowns. Validate will eventually be called again once | ||
1471 | // all values are known. | ||
1472 | if isProto5() && !isWhollyKnown(raw) { | ||
1473 | return nil, nil | ||
1474 | } | ||
1475 | |||
1435 | // Validate length | 1476 | // Validate length |
1436 | if schema.MaxItems > 0 && rawV.Len() > schema.MaxItems { | 1477 | if schema.MaxItems > 0 && rawV.Len() > schema.MaxItems { |
1437 | return nil, []error{fmt.Errorf( | 1478 | return nil, []error{fmt.Errorf( |
@@ -1489,11 +1530,15 @@ func (m schemaMap) validateMap( | |||
1489 | c *terraform.ResourceConfig) ([]string, []error) { | 1530 | c *terraform.ResourceConfig) ([]string, []error) { |
1490 | // first check if the list is wholly unknown | 1531 | // first check if the list is wholly unknown |
1491 | if s, ok := raw.(string); ok { | 1532 | if s, ok := raw.(string); ok { |
1492 | if s == config.UnknownVariableValue { | 1533 | if s == hcl2shim.UnknownVariableValue { |
1493 | return nil, nil | 1534 | return nil, nil |
1494 | } | 1535 | } |
1495 | } | 1536 | } |
1496 | 1537 | ||
1538 | // schemaMap can't validate nil | ||
1539 | if raw == nil { | ||
1540 | return nil, nil | ||
1541 | } | ||
1497 | // We use reflection to verify the slice because you can't | 1542 | // We use reflection to verify the slice because you can't |
1498 | // case to []interface{} unless the slice is exactly that type. | 1543 | // case to []interface{} unless the slice is exactly that type. |
1499 | rawV := reflect.ValueOf(raw) | 1544 | rawV := reflect.ValueOf(raw) |
@@ -1620,6 +1665,12 @@ func (m schemaMap) validateObject( | |||
1620 | schema map[string]*Schema, | 1665 | schema map[string]*Schema, |
1621 | c *terraform.ResourceConfig) ([]string, []error) { | 1666 | c *terraform.ResourceConfig) ([]string, []error) { |
1622 | raw, _ := c.Get(k) | 1667 | raw, _ := c.Get(k) |
1668 | |||
1669 | // schemaMap can't validate nil | ||
1670 | if raw == nil { | ||
1671 | return nil, nil | ||
1672 | } | ||
1673 | |||
1623 | if _, ok := raw.(map[string]interface{}); !ok && !c.IsComputed(k) { | 1674 | if _, ok := raw.(map[string]interface{}); !ok && !c.IsComputed(k) { |
1624 | return nil, []error{fmt.Errorf( | 1675 | return nil, []error{fmt.Errorf( |
1625 | "%s: expected object, got %s", | 1676 | "%s: expected object, got %s", |
@@ -1664,6 +1715,14 @@ func (m schemaMap) validatePrimitive( | |||
1664 | raw interface{}, | 1715 | raw interface{}, |
1665 | schema *Schema, | 1716 | schema *Schema, |
1666 | c *terraform.ResourceConfig) ([]string, []error) { | 1717 | c *terraform.ResourceConfig) ([]string, []error) { |
1718 | |||
1719 | // a nil value shouldn't happen in the old protocol, and in the new | ||
1720 | // protocol the types have already been validated. Either way, we can't | ||
1721 | // reflect on nil, so don't panic. | ||
1722 | if raw == nil { | ||
1723 | return nil, nil | ||
1724 | } | ||
1725 | |||
1667 | // Catch if the user gave a complex type where a primitive was | 1726 | // Catch if the user gave a complex type where a primitive was |
1668 | // expected, so we can return a friendly error message that | 1727 | // expected, so we can return a friendly error message that |
1669 | // doesn't contain Go type system terminology. | 1728 | // doesn't contain Go type system terminology. |