Hi @apparentlymart .
This is what I have so far.
package main
import (
// "bytes"
"os"
"log"
"fmt"
"github.com/buger/jsonparser"
"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/hclwrite"
"github.com/zclconf/go-cty/cty"
// "github.com/hashicorp/hcl/v2/hclsyntax"
// "reflect"
"sort"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"encoding/json"
tfjson "github.com/hashicorp/terraform-json"
)
func main(){
vars := hclwrite.NewEmptyFile()
vars_root_body := vars.Body()
vars_file, vars_create_err := os.Create("variables.tf")
if vars_create_err != nil{
log.Fatal(vars_create_err)
}
vars_block := vars_root_body.AppendNewBlock("variable",[]string{"default_variable"})
vars_block_body := vars_block.Body()
vars_block_body.SetAttributeRaw(
"type",
getVariableType(cty.Tuple([]cty.Type{cty.Bool,cty.String})),
)
fmt.Printf("%s", vars.Bytes())
}
func getVariableType(cty_type cty.Type) hclwrite.Tokens {
switch cty_type {
case cty.String:
return hclwrite.TokensForIdentifier("string")
case cty.Bool:
return hclwrite.TokensForIdentifier("bool")
case cty.Number:
return hclwrite.TokensForIdentifier("number")
case cty.DynamicPseudoType:
return hclwrite.TokensForIdentifier("any")
case cty.NilType:
return hclwrite.TokensForIdentifier("null")
}
if cty_type.IsCollectionType() {
etyTokens := getVariableType(cty_type.ElementType())
switch {
case cty_type.IsListType():
return hclwrite.TokensForFunctionCall("list", etyTokens)
case cty_type.IsSetType():
return hclwrite.TokensForFunctionCall("set", etyTokens)
case cty_type.IsMapType():
return hclwrite.TokensForFunctionCall("map", etyTokens)
default:
// Should never happen because the above is exhaustive
panic("unsupported collection type")
}
}
if cty_type.IsObjectType() {
atys := cty_type.AttributeTypes()
names := make([]string, 0, len(atys))
for name := range atys {
names = append(names, name)
}
sort.Strings(names)
items := make([]hclwrite.ObjectAttrTokens, len(names))
for i, name := range names {
items[i] = hclwrite.ObjectAttrTokens{
Name: hclwrite.TokensForIdentifier(name),
Value: getVariableType(atys[name]),
}
}
return hclwrite.TokensForObject(items)
}
if cty_type.IsTupleType() {
fmt.Println("Inside Tuple")
etys := cty_type.TupleElementTypes()
items := make([]hclwrite.Tokens, len(etys))
for i, ety := range etys {
items[i] = getVariableType(ety)
}
return hclwrite.TokensForTuple(items)
}
panic(fmt.Errorf("unsupported type %#v", cty_type))
}
So for now am manually passing the type constraint to this “getVariableType” func , and getting the type. What I am looking for is to read the type constraint value for nested types such as " "type": [ "map", "string" ], or "type": [ "list", "string" ], or more complex like this : "type": [ "list", [ "object", { "metadata": [ "list", [ "object", { "annotations": [ "map", "string" ], "generation": "number", "labels": [ "map", "string" ], "name": "string", "namespace": "string", "resource_version": "string", "self_link": "string", "uid": "string" } ] ], "spec": [ "list", [ "object", { "container_concurrency": "number", "containers": [ "list", [ "object", { "args": [ "list", "string" ], "command": [ "list", "string" ], "env": [ "set", [ "object", { "name": "string", "value": "string", "value_from": [ "list", [ "object", { "secret_key_ref": [ "list", [ "object", { "key": "string", "name": "string" } ] ] } ] ] } ] ], "env_from": [ "list", [ "object", { "config_map_ref": [ "list", [ "object", { "local_object_reference": [ "list", [ "object", { "name": "string" } ] ], "optional": "bool" } ] ], "prefix": "string", "secret_ref": [ "list", [ "object", { "local_object_reference": [ "list", [ "object", { "name": "string" } ] ], "optional": "bool" } ] ] } ] ], "image": "string", "ports": [ "list", [ "object", { "container_port": "number", "name": "string", "protocol": "string" } ] ], "resources": [ "list", [ "object", { "limits": [ "map", "string" ], "requests": [ "map", "string" ] } ] ], "volume_mounts": [ "list", [ "object", { "mount_path": "string", "name": "string" } ] ], "working_dir": "string" } ] ], "service_account_name": "string", "serving_state": "string", "timeout_seconds": "number", "volumes": [ "list", [ "object", { "name": "string", "secret": [ "list", [ "object", { "default_mode": "number", "items": [ "list", [ "object", { "key": "string", "mode": "number", "path": "string" } ] ], "secret_name": "string" } ] ] } ] ] } ] ] } ], "test" ]
which becomes more complex for nested type constraints.
All this is coming from the json file which I got from running “terraform providers schema -json”
The above func was also a courtesy from StackOverflow help (go - Get the type of value using cty in hclwrite - Stack Overflow)
I would really really appreciate if you help me one example of how we can get the type constraint for a nested type - and I can try from there on for more complex types.
Can we terraform-json go-pkg to fetch the type ? and then store it in cty.type and then parse it via hcl pkg ?