hcl
hcl copied to clipboard
How to define a struct to parse list of objects resource in hcl file. Keep getting `panic: unsuitable DecodeExpression target: no cty.Type (no cty field tags)`
HCL Template
resource "test" "test-policy" {
src_security_zone = src_sz
dst_security_zone = dst_sz
name = "testpolicy"
acl_type = "pba"
applied_on = "dst"
approval_ticket = "20501"
ports = [{ approval_ticket = "23653", port_range = "9000", protocol = "tcp" }, { approval_ticket = "23653", port_range = "10504", protocol = "tcp" },]
}
I defined the structure for parsing the above HCL file as below.
type NaclPolicyPort struct {
PortRange string `hcl:"port_range,attr"`
Protocol string `hcl:"protocol,attr"`
ApprovalTicket string `hcl:"approval_ticket,attr"`
}
type NaclPolicyResource struct{
LabelNaclPolicy string `hcl:"name,label"`
LabelNaclPolicyName string `hcl:"name,label"`
Name string `hcl:"name,attr"`
SrcSecurityZone string `hcl:"src_security_zone,attr"`
DstSecurityZone string `hcl:"dst_security_zone,attr"`
AclType string `hcl:"acl_type,attr"`
AppliedOn string `hcl:"applied_on,attr"`
ApprovalTicket string `hcl:"approval_ticket,attr"`
Ports []NaclPolicyPort `hcl:"ports"`
}
Expected behavior
What should have happened?
I get an error when my program tries to parse hcl:ports as below.
panic: unsuitable DecodeExpression target: no cty.Type for main.NaclPolicyPort (no cty field tags)
Actual behavior
What actually happened? I was expecting this to be parsed and I should have been able to get the ports.
Hey @hrdivyashree, I am having the same issue, were you able to find a solution ?
Not OP, but I got it to work by replacing hcl with cty in the child struct's tags, but couldn't figure out how to use optional fields. :confused:
This is a serious issue when using gohcl...
type NaclPolicyPort struct {
PortRange string `cty:"port_range"`
Protocol string `cty:"protocol"`
ApprovalTicket string `cty:"approval_ticket"`
}
Same here and this issue is worse when the list of maps contain an expression. Still have not gotten it to work, example
data = [{url=dependency.urls[0]}]
I tried decoding it with
type Net struct {
URL hcl.Expression `hcl:"url,attr"`
}
type Config struct {
Data []URL `hcl:"data,attr"`
}
This gives me a panic
Instread of using a Port struct you can use:
Ports []map[string]string `hcl:"ports,attr"`
I'm assuming this is because it's an unnamed block? [ { stuff = stuff } ]. I'm not sure how you'd do it for mixed types, an interface maybe.
Thank you for the hint @b0bu. Unfortunately, an interface doesn't work either. Here's my code example with using interface{}:
const inputBody = `module "module1" {
source = "../../modules/pipeline"
steps = [
{
name = "Step1",
type = "manualApproval",
params = {
server = "one",
},
},
]
}
`
type Step struct {
Name string `hcl:"name"`
Type string `hcl:"type"`
DependsOn []string `hcl:"dependsOn,optional"`
Params map[string]string `hcl:"params,attr"`
Remain hcl.Body `hcl:",remain"`
}
type Steps []Step
type Pipeline struct {
Name string `hcl:",label"`
Source string `hcl:"source"`
Steps []map[string]interface{} `hcl:"steps,attr"`
Remain hcl.Body `hcl:",remain"`
}
type Module struct {
Module Pipeline `hcl:"module,block"`
}
And here's the error I get:
panic: unsuitable DecodeExpression target: no cty.Type for interface {}
goroutine 1 [running]:
github.com/hashicorp/hcl/v2/gohcl.DecodeExpression({0x14ac210, 0xc0000f4780}, 0x11d01c0?, {0xc0000fe6c0, 0xc0000f20c0})
/Users/bilen/go/pkg/mod/github.com/hashicorp/hcl/[email protected]/gohcl/decode.go:296 +0x82c
github.com/hashicorp/hcl/v2/gohcl.decodeBodyToStruct({0x12559e8, 0xc0000d2420}, 0x1?, {0x11ec2c0?, 0xc0000f20a0?, 0x1?})
/Users/bilen/go/pkg/mod/github.com/hashicorp/hcl/[email protected]/gohcl/decode.go:127 +0xe5f
github.com/hashicorp/hcl/v2/gohcl.decodeBodyToValue({0x12559e8, 0xc0000d2420}, 0x12?, {0x11ec2c0?, 0xc0000f20a0?, 0x1?})
/Users/bilen/go/pkg/mod/github.com/hashicorp/hcl/[email protected]/gohcl/decode.go:46 +0xc5
github.com/hashicorp/hcl/v2/gohcl.decodeBlockToValue(0xc00009ef70, 0xc0000f20a0?, {0x11ec2c0?, 0xc0000f20a0?, 0x12578a0?})
/Users/bilen/go/pkg/mod/github.com/hashicorp/hcl/[email protected]/gohcl/decode.go:264 +0x72
github.com/hashicorp/hcl/v2/gohcl.decodeBodyToStruct({0x12559e8, 0xc0000d24d0}, 0xc000142000?, {0x11dd7e0?, 0xc0000f20a0?, 0x9b?})
/Users/bilen/go/pkg/mod/github.com/hashicorp/hcl/[email protected]/gohcl/decode.go:227 +0x2125
github.com/hashicorp/hcl/v2/gohcl.decodeBodyToValue({0x12559e8, 0xc0000d24d0}, 0x0?, {0x11dd7e0?, 0xc0000f20a0?, 0x0?})
/Users/bilen/go/pkg/mod/github.com/hashicorp/hcl/[email protected]/gohcl/decode.go:46 +0xc5
github.com/hashicorp/hcl/v2/gohcl.DecodeBody({0x12559e8, 0xc0000d24d0}, 0x334?, {0x11cd840?, 0xc0000f20a0?})
/Users/bilen/go/pkg/mod/github.com/hashicorp/hcl/[email protected]/gohcl/decode.go:39 +0x105
main.main()
/Users/bilen/src/bilenkis/cources/hcl-parser/main.go:83 +0x18c
exit status 2
Using cty instead of hcl allows me to parse the structure properly but doesn't solve the issue with optional fields.
Are there any other workarounds? I'm happy to test them out. Thanks!