mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-25 18:45:20 -06:00
Merge pull request #15723 from hashicorp/f-get-boolean-non-default
core: Add `GetOkExists` schema function
This commit is contained in:
commit
3600f0b730
@ -104,6 +104,22 @@ func (d *ResourceData) GetOk(key string) (interface{}, bool) {
|
|||||||
return r.Value, exists
|
return r.Value, exists
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetOkExists returns the data for a given key and whether or not the key
|
||||||
|
// has been set to a non-zero value. This is only useful for determining
|
||||||
|
// if boolean attributes have been set, if they are Optional but do not
|
||||||
|
// have a Default value.
|
||||||
|
//
|
||||||
|
// This is nearly the same function as GetOk, yet it does not check
|
||||||
|
// for the zero value of the attribute's type. This allows for attributes
|
||||||
|
// without a default, to fully check for a literal assignment, regardless
|
||||||
|
// of the zero-value for that type.
|
||||||
|
// This should only be used if absolutely required/needed.
|
||||||
|
func (d *ResourceData) GetOkExists(key string) (interface{}, bool) {
|
||||||
|
r := d.getRaw(key, getSourceSet)
|
||||||
|
exists := r.Exists && !r.Computed
|
||||||
|
return r.Value, exists
|
||||||
|
}
|
||||||
|
|
||||||
func (d *ResourceData) getRaw(key string, level getSource) getResult {
|
func (d *ResourceData) getRaw(key string, level getSource) getResult {
|
||||||
var parts []string
|
var parts []string
|
||||||
if key != "" {
|
if key != "" {
|
||||||
|
@ -1082,6 +1082,258 @@ func TestResourceDataGetOk(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestResourceDataGetOkExists(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
Name string
|
||||||
|
Schema map[string]*Schema
|
||||||
|
State *terraform.InstanceState
|
||||||
|
Diff *terraform.InstanceDiff
|
||||||
|
Key string
|
||||||
|
Value interface{}
|
||||||
|
Ok bool
|
||||||
|
}{
|
||||||
|
/*
|
||||||
|
* Primitives
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
Name: "string-literal-empty",
|
||||||
|
Schema: map[string]*Schema{
|
||||||
|
"availability_zone": {
|
||||||
|
Type: TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
State: nil,
|
||||||
|
|
||||||
|
Diff: &terraform.InstanceDiff{
|
||||||
|
Attributes: map[string]*terraform.ResourceAttrDiff{
|
||||||
|
"availability_zone": {
|
||||||
|
Old: "",
|
||||||
|
New: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
Key: "availability_zone",
|
||||||
|
Value: "",
|
||||||
|
Ok: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
Name: "string-computed-empty",
|
||||||
|
Schema: map[string]*Schema{
|
||||||
|
"availability_zone": {
|
||||||
|
Type: TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
State: nil,
|
||||||
|
|
||||||
|
Diff: &terraform.InstanceDiff{
|
||||||
|
Attributes: map[string]*terraform.ResourceAttrDiff{
|
||||||
|
"availability_zone": {
|
||||||
|
Old: "",
|
||||||
|
New: "",
|
||||||
|
NewComputed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
Key: "availability_zone",
|
||||||
|
Value: "",
|
||||||
|
Ok: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
Name: "string-optional-computed-nil-diff",
|
||||||
|
Schema: map[string]*Schema{
|
||||||
|
"availability_zone": {
|
||||||
|
Type: TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
State: nil,
|
||||||
|
|
||||||
|
Diff: nil,
|
||||||
|
|
||||||
|
Key: "availability_zone",
|
||||||
|
Value: "",
|
||||||
|
Ok: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Lists
|
||||||
|
*/
|
||||||
|
|
||||||
|
{
|
||||||
|
Name: "list-optional",
|
||||||
|
Schema: map[string]*Schema{
|
||||||
|
"ports": {
|
||||||
|
Type: TypeList,
|
||||||
|
Optional: true,
|
||||||
|
Elem: &Schema{Type: TypeInt},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
State: nil,
|
||||||
|
|
||||||
|
Diff: nil,
|
||||||
|
|
||||||
|
Key: "ports",
|
||||||
|
Value: []interface{}{},
|
||||||
|
Ok: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Map
|
||||||
|
*/
|
||||||
|
|
||||||
|
{
|
||||||
|
Name: "map-optional",
|
||||||
|
Schema: map[string]*Schema{
|
||||||
|
"ports": {
|
||||||
|
Type: TypeMap,
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
State: nil,
|
||||||
|
|
||||||
|
Diff: nil,
|
||||||
|
|
||||||
|
Key: "ports",
|
||||||
|
Value: map[string]interface{}{},
|
||||||
|
Ok: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set
|
||||||
|
*/
|
||||||
|
|
||||||
|
{
|
||||||
|
Name: "set-optional",
|
||||||
|
Schema: map[string]*Schema{
|
||||||
|
"ports": {
|
||||||
|
Type: TypeSet,
|
||||||
|
Optional: true,
|
||||||
|
Elem: &Schema{Type: TypeInt},
|
||||||
|
Set: func(a interface{}) int { return a.(int) },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
State: nil,
|
||||||
|
|
||||||
|
Diff: nil,
|
||||||
|
|
||||||
|
Key: "ports",
|
||||||
|
Value: []interface{}{},
|
||||||
|
Ok: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
Name: "set-optional-key",
|
||||||
|
Schema: map[string]*Schema{
|
||||||
|
"ports": {
|
||||||
|
Type: TypeSet,
|
||||||
|
Optional: true,
|
||||||
|
Elem: &Schema{Type: TypeInt},
|
||||||
|
Set: func(a interface{}) int { return a.(int) },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
State: nil,
|
||||||
|
|
||||||
|
Diff: nil,
|
||||||
|
|
||||||
|
Key: "ports.0",
|
||||||
|
Value: 0,
|
||||||
|
Ok: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
Name: "bool-literal-empty",
|
||||||
|
Schema: map[string]*Schema{
|
||||||
|
"availability_zone": {
|
||||||
|
Type: TypeBool,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
State: nil,
|
||||||
|
Diff: &terraform.InstanceDiff{
|
||||||
|
Attributes: map[string]*terraform.ResourceAttrDiff{
|
||||||
|
"availability_zone": {
|
||||||
|
Old: "",
|
||||||
|
New: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
Key: "availability_zone",
|
||||||
|
Value: false,
|
||||||
|
Ok: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
Name: "bool-literal-set",
|
||||||
|
Schema: map[string]*Schema{
|
||||||
|
"availability_zone": {
|
||||||
|
Type: TypeBool,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
State: nil,
|
||||||
|
|
||||||
|
Diff: &terraform.InstanceDiff{
|
||||||
|
Attributes: map[string]*terraform.ResourceAttrDiff{
|
||||||
|
"availability_zone": {
|
||||||
|
New: "true",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
Key: "availability_zone",
|
||||||
|
Value: true,
|
||||||
|
Ok: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, tc := range cases {
|
||||||
|
t.Run(fmt.Sprintf("%d-%s", i, tc.Name), func(t *testing.T) {
|
||||||
|
d, err := schemaMap(tc.Schema).Data(tc.State, tc.Diff)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("%s err: %s", tc.Name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
v, ok := d.GetOkExists(tc.Key)
|
||||||
|
if s, ok := v.(*Set); ok {
|
||||||
|
v = s.List()
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(v, tc.Value) {
|
||||||
|
t.Fatalf("Bad %s: \n%#v", tc.Name, v)
|
||||||
|
}
|
||||||
|
if ok != tc.Ok {
|
||||||
|
t.Fatalf("%s: expected ok: %t, got: %t", tc.Name, tc.Ok, ok)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestResourceDataTimeout(t *testing.T) {
|
func TestResourceDataTimeout(t *testing.T) {
|
||||||
cases := []struct {
|
cases := []struct {
|
||||||
Name string
|
Name string
|
||||||
|
Loading…
Reference in New Issue
Block a user