mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-25 18:45:20 -06:00
wrap JSON strings as jsonencode calls on generate-config-out (#1595)
Signed-off-by: ollevche <ollevche@gmail.com> Signed-off-by: Oleksandr Levchenkov <ollevche@gmail.com>
This commit is contained in:
parent
82a6797894
commit
b7098f50cb
@ -6,6 +6,7 @@ NEW FEATURES:
|
|||||||
|
|
||||||
ENHANCEMENTS:
|
ENHANCEMENTS:
|
||||||
* Added `tofu test -json` types to website Machine-Readable UI documentation ([1408](https://github.com/opentofu/opentofu/issues/1408))
|
* Added `tofu test -json` types to website Machine-Readable UI documentation ([1408](https://github.com/opentofu/opentofu/issues/1408))
|
||||||
|
* Made `tofu plan` with `generate-config-out` flag replace JSON strings with `jsonencode` functions calls. ([#1595](https://github.com/opentofu/opentofu/pull/1595))
|
||||||
|
|
||||||
BUG FIXES:
|
BUG FIXES:
|
||||||
* Fixed crash in gcs backend when using certain commands ([#1618](https://github.com/opentofu/opentofu/pull/1618))
|
* Fixed crash in gcs backend when using certain commands ([#1618](https://github.com/opentofu/opentofu/pull/1618))
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
package genconfig
|
package genconfig
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
@ -13,6 +14,7 @@ import (
|
|||||||
"github.com/hashicorp/hcl/v2"
|
"github.com/hashicorp/hcl/v2"
|
||||||
"github.com/hashicorp/hcl/v2/hclwrite"
|
"github.com/hashicorp/hcl/v2/hclwrite"
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
|
"github.com/zclconf/go-cty/cty/json"
|
||||||
|
|
||||||
"github.com/opentofu/opentofu/internal/addrs"
|
"github.com/opentofu/opentofu/internal/addrs"
|
||||||
"github.com/opentofu/opentofu/internal/configs/configschema"
|
"github.com/opentofu/opentofu/internal/configs/configschema"
|
||||||
@ -160,7 +162,7 @@ func writeConfigAttributesFromExisting(addr addrs.AbsResourceInstance, buf *stri
|
|||||||
if attrS.Sensitive || val.IsMarked() {
|
if attrS.Sensitive || val.IsMarked() {
|
||||||
buf.WriteString("null # sensitive")
|
buf.WriteString("null # sensitive")
|
||||||
} else {
|
} else {
|
||||||
tok := hclwrite.TokensForValue(val)
|
tok := tryWrapAsJsonEncodeFunctionCall(val)
|
||||||
if _, err := tok.WriteTo(buf); err != nil {
|
if _, err := tok.WriteTo(buf); err != nil {
|
||||||
diags = diags.Append(&hcl.Diagnostic{
|
diags = diags.Append(&hcl.Diagnostic{
|
||||||
Severity: hcl.DiagWarning,
|
Severity: hcl.DiagWarning,
|
||||||
@ -592,3 +594,40 @@ func omitUnknowns(val cty.Value) cty.Value {
|
|||||||
panic(fmt.Sprintf("omitUnknowns cannot handle %#v", val))
|
panic(fmt.Sprintf("omitUnknowns cannot handle %#v", val))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func tryWrapAsJsonEncodeFunctionCall(v cty.Value) hclwrite.Tokens {
|
||||||
|
tokens, err := wrapAsJSONEncodeFunctionCall(v)
|
||||||
|
if err != nil {
|
||||||
|
return hclwrite.TokensForValue(v)
|
||||||
|
}
|
||||||
|
return tokens
|
||||||
|
}
|
||||||
|
|
||||||
|
func wrapAsJSONEncodeFunctionCall(v cty.Value) (hclwrite.Tokens, error) {
|
||||||
|
if v.IsNull() || v.Type() != cty.String || !v.IsKnown() {
|
||||||
|
return nil, errors.New("value cannot be treated as JSON string")
|
||||||
|
}
|
||||||
|
|
||||||
|
s := []byte(strings.TrimSpace(v.AsString()))
|
||||||
|
if len(s) == 0 {
|
||||||
|
return nil, errors.New("empty value")
|
||||||
|
}
|
||||||
|
|
||||||
|
if s[0] != '{' && s[0] != '[' {
|
||||||
|
return nil, errors.New("value is not a JSON object, nor a JSON array")
|
||||||
|
}
|
||||||
|
|
||||||
|
t, err := json.ImpliedType(s)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot define implied cty type (possibly not a JSON string): %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
v, err = json.Unmarshal(s, t)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot unmarshal using implied type (possible not a JSON string): %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tokens := hclwrite.TokensForFunctionCall("jsonencode", hclwrite.TokensForValue(v))
|
||||||
|
|
||||||
|
return tokens, nil
|
||||||
|
}
|
||||||
|
@ -423,6 +423,73 @@ resource "tfcoremock_simple_resource" "empty" {
|
|||||||
list = null
|
list = null
|
||||||
map = null
|
map = null
|
||||||
single = null
|
single = null
|
||||||
|
}`,
|
||||||
|
},
|
||||||
|
"jsonencode_wrapping": {
|
||||||
|
schema: &configschema.Block{
|
||||||
|
Attributes: map[string]*configschema.Attribute{
|
||||||
|
"juststr": {
|
||||||
|
Type: cty.String,
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
"jsonobj": {
|
||||||
|
Type: cty.String,
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
"jsonarr": {
|
||||||
|
Type: cty.String,
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
"sensitivejsonobj": {
|
||||||
|
Type: cty.String,
|
||||||
|
Optional: true,
|
||||||
|
Sensitive: true,
|
||||||
|
},
|
||||||
|
"secrets": {
|
||||||
|
Type: cty.Object(map[string]cty.Type{
|
||||||
|
"main": cty.String,
|
||||||
|
"secondary": cty.String,
|
||||||
|
}),
|
||||||
|
Optional: true,
|
||||||
|
Sensitive: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
addr: addrs.AbsResourceInstance{
|
||||||
|
Module: nil,
|
||||||
|
Resource: addrs.ResourceInstance{
|
||||||
|
Resource: addrs.Resource{
|
||||||
|
Mode: addrs.ManagedResourceMode,
|
||||||
|
Type: "tfcoremock_simple_resource",
|
||||||
|
Name: "example",
|
||||||
|
},
|
||||||
|
Key: nil,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
provider: addrs.LocalProviderConfig{
|
||||||
|
LocalName: "tfcoremock",
|
||||||
|
},
|
||||||
|
value: cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"juststr": cty.StringVal("{a=b}"),
|
||||||
|
"jsonobj": cty.StringVal(`{"SomeDate":"2012-10-17"}`),
|
||||||
|
"jsonarr": cty.StringVal(`[{"a": 1}]`),
|
||||||
|
"sensitivejsonobj": cty.StringVal(`{"SomePassword":"dontstealplease"}`),
|
||||||
|
"secrets": cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"main": cty.StringVal(`{"v":"mypass"}`),
|
||||||
|
"secondary": cty.StringVal(`{"v":"mybackup"}`),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
expected: `
|
||||||
|
resource "tfcoremock_simple_resource" "example" {
|
||||||
|
jsonarr = jsonencode([{
|
||||||
|
a = 1
|
||||||
|
}])
|
||||||
|
jsonobj = jsonencode({
|
||||||
|
SomeDate = "2012-10-17"
|
||||||
|
})
|
||||||
|
juststr = "{a=b}"
|
||||||
|
secrets = null # sensitive
|
||||||
|
sensitivejsonobj = null # sensitive
|
||||||
}`,
|
}`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user