validate integers when using protoV5
The new type system only has a Number type, but helper schema differentiates between Int and Float values. Verify that a new config value is an integer during Validate, because the existing WeakDecode validation will decode a float value into an integer while the config FieldReader will attempt to parse the float exactly. Since we're limiting this to protoV5, we can be certain that any valid config value will be converted to an `int` type by the shims. The only case where an integral float value will appear is if the integer is out of range for the systems `int` type, but we also need to prevent that anyway since it would fail to read in the same manner.
This commit is contained in:
parent
28b2383eac
commit
6bc36d3321
|
@ -153,6 +153,10 @@ func testResource() *schema.Resource {
|
||||||
Optional: true,
|
Optional: true,
|
||||||
Description: "do not set in config",
|
Description: "do not set in config",
|
||||||
},
|
},
|
||||||
|
"int": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1029,3 +1029,24 @@ resource "test_resource" "foo" {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestResource_floatInIntAttr(t *testing.T) {
|
||||||
|
resource.UnitTest(t, resource.TestCase{
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckResourceDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: strings.TrimSpace(`
|
||||||
|
resource "test_resource" "foo" {
|
||||||
|
required = "yep"
|
||||||
|
required_map = {
|
||||||
|
key = "value"
|
||||||
|
}
|
||||||
|
int = 40.2
|
||||||
|
}
|
||||||
|
`),
|
||||||
|
ExpectError: regexp.MustCompile(`must be a whole number, got 40.2`),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -1731,12 +1731,25 @@ func (m schemaMap) validatePrimitive(
|
||||||
}
|
}
|
||||||
decoded = n
|
decoded = n
|
||||||
case TypeInt:
|
case TypeInt:
|
||||||
|
switch {
|
||||||
|
case isProto5():
|
||||||
|
// We need to verify the type precisely, because WeakDecode will
|
||||||
|
// decode a float as an integer.
|
||||||
|
|
||||||
|
// the config shims only use int for integral number values
|
||||||
|
if v, ok := raw.(int); ok {
|
||||||
|
decoded = v
|
||||||
|
} else {
|
||||||
|
return nil, []error{fmt.Errorf("%s: must be a whole number, got %v", k, raw)}
|
||||||
|
}
|
||||||
|
default:
|
||||||
// Verify that we can parse this as an int
|
// Verify that we can parse this as an int
|
||||||
var n int
|
var n int
|
||||||
if err := mapstructure.WeakDecode(raw, &n); err != nil {
|
if err := mapstructure.WeakDecode(raw, &n); err != nil {
|
||||||
return nil, []error{fmt.Errorf("%s: %s", k, err)}
|
return nil, []error{fmt.Errorf("%s: %s", k, err)}
|
||||||
}
|
}
|
||||||
decoded = n
|
decoded = n
|
||||||
|
}
|
||||||
case TypeFloat:
|
case TypeFloat:
|
||||||
// Verify that we can parse this as an int
|
// Verify that we can parse this as an int
|
||||||
var n float64
|
var n float64
|
||||||
|
|
Loading…
Reference in New Issue