Hi All,
I am trying the dynamically manipulate the tfvars file using golang.
Here is my code
package main
import (
"fmt"
"io"
"log"
"os"
"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/gohcl"
"github.com/hashicorp/hcl/v2/hclsyntax"
"github.com/hashicorp/hcl/v2/hclwrite"
)
type RawDatabase struct {
Name string `hcl:"name"`
BusinessVerticalID string `hcl:"business_vertical_id"`
Readers []string `hcl:"readers"`
Contributors []string `hcl:"contributors"`
}
type Config struct {
Environment string `hcl:"environment"`
BusinessEntity *string `hcl:"business_entity"`
EntitlementLookup map[string]string `hcl:"entitlement_lookup"`
RawDatabases []RawDatabase `hcl:"raw_databases"`
}
func readFile(filePath string) ([]byte, error) {
// Open the file for reading
file, err := os.Open(filePath)
if err != nil {
return nil, err
}
defer file.Close()
// Read the file content into a byte slice
content, err := io.ReadAll(file)
if err != nil {
return nil, err
}
return content, nil
}
func writeFile(data []byte, filePath string) ( error) {
// Open the file for reading
file, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE, 0644)
if err != nil {
return err
}
defer file.Close()
// Read the file content into a byte slice
_, err = file.Write(data)
if err != nil {
return err
}
return nil
}
func main() {
// Read the tfvar file content
content, err := readFile("demo.tfvars")
if err != nil {
log.Fatalf("Error reading tfvars file: %v", err)
}
// Parse tfvars content
parsedObject, diags := hclsyntax.ParseConfig(content, "", hcl.Pos{})
if diags.HasErrors() {
log.Fatalf("Failed to parse tfvars content: %s", diags)
}
// Print parsedObject.Body to debug
fmt.Println("Parsed Body:", parsedObject.Body)
// Decode HCL into Go struct
var config Config
diags = gohcl.DecodeBody(parsedObject.Body, nil, &config)
if diags.HasErrors() {
log.Fatalf("Failed to decode tfvars content: %s", diags)
}
// Print Go struct
fmt.Printf("%+v\n", config)
// Convert Go struct back to HCL
f := hclwrite.NewEmptyFile()
gohcl.EncodeIntoBody(&config, f.Body())
// Write HCL content to a file
err = writeFile(f.Bytes(), "../../../terraform/project1/dev_out.tfvars")
if err != nil {
log.Fatalf("Failed to write HCL to file: %v", err)
}
}
and the demo.tfvars
file content is
environment = "dev"
entitlement_lookup = {
"obj1" = "obj_id1",
"obj2" = "obj_id2",
}
raw_databases = [
{
name = "db1"
business_vertical_id = "fin"
readers = []
contributors = ["obj1", "obj2"]
},
{
name = "db2"
business_vertical_id = "fin"
readers = []
contributors = ["obj2"]
},
{
name = "db3"
business_vertical_id = "fin"
readers = []
contributors = ["obj1"]
}
]
Help me to solve the error
panic: unsuitable DecodeExpression target: no cty.Type for main.RawDatabase (no cty field tags)
goroutine 1 [running]:
github.com/hashicorp/hcl/v2/gohcl.DecodeExpression({0x7fdab078cc68, 0xc0000fa8c0}, 0x5f54e0?, {0xc0000bbc80, 0xc0000bb9a0})
/go/pkg/mod/github.com/hashicorp/hcl/v2@v2.20.1/gohcl/decode.go:296 +0x7f4
github.com/hashicorp/hcl/v2/gohcl.decodeBodyToStruct({0x68cb58, 0xc000136420}, 0x0, {0x615b80?, 0xc0000bb980?, 0xc00019fe00?})
/go/pkg/mod/github.com/hashicorp/hcl/v2@v2.20.1/gohcl/decode.go:127 +0xd38
github.com/hashicorp/hcl/v2/gohcl.decodeBodyToValue({0x68cb58, 0xc000136420}, 0x0, {0x615b80?, 0xc0000bb980?, 0xc00019fe78?})
/go/pkg/mod/github.com/hashicorp/hcl/v2@v2.20.1/gohcl/decode.go:46 +0xba
github.com/hashicorp/hcl/v2/gohcl.DecodeBody({0x68cb58, 0xc000136420}, 0x0, {0x5f2060?, 0xc0000bb980?})
/go/pkg/mod/github.com/hashicorp/hcl/v2@v2.20.1/gohcl/decode.go:39 +0xc5
main.main()
/workspaces/cdassp/go/cmd/go_hcl/main.go:106 +0x1bd
exit status 2
Does this mean the struct objects can not be parsed with HCL?