HCL 解码:具有多个标签的块
学习知识要善于思考,思考,再思考!今天编程网小编就给大家带来《HCL 解码:具有多个标签的块》,以下内容主要包含等知识点,如果你正在学习或准备学习Golang,就都不要错过本文啦~让我们一起来看看吧,能帮助到你就更好了!
问题内容我的目标是解析 hcl 配置(terraform configuration),然后将收集到的有关变量、输出、资源块和数据块的数据写入 markdown 文件中。
但是,一旦我尝试解码具有多个标签的资源块,变量和输出就没有问题。
作品:
variable "foo" {
type = "bar"
}
不起作用:
resource "foo" "bar" {
name = "biz"
}
错误:资源的额外标签;资源块仅需要 1 个标签(名称)。
类型声明代码:
import (
"log"
"os"
"strconv"
"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/gohcl"
"github.com/hashicorp/hcl/v2/hclsyntax"
)
type variable struct {
name string `hcl:",label"`
description string `hcl:"description,optional"`
sensitive bool `hcl:"sensitive,optional"`
type *hcl.attribute `hcl:"type,optional"`
default *hcl.attribute `hcl:"default,optional"`
options hcl.body `hcl:",remain"`
}
type output struct {
name string `hcl:",label"`
description string `hcl:"description,optional"`
sensitive bool `hcl:"sensitive,optional"`
value string `hcl:"value,optional"`
options hcl.body `hcl:",remain"`
}
type resource struct {
name string `hcl:"name,label"`
options hcl.body `hcl:",remain"`
}
type data struct {
name string `hcl:"name,label"`
options hcl.body `hcl:",remain"`
}
type config struct {
outputs []*output `hcl:"output,block"`
variables []*variable `hcl:"variable,block"`
resources []*resource `hcl:"resource,block"`
data []*data `hcl:"data,block"`
}
解码代码:
func createDocs(hclPath string) map[string][]map[string]string {
var variables, outputs []map[string]string
parsedConfig := make(map[string][]map[string]string)
hclConfig := make(map[string][]byte)
c := &Config{}
// Iterate all Terraform files and safe the contents in the hclConfig map
for _, file := range filesInDirectory(hclPath, ".tf") {
fileContent, err := os.ReadFile(hclPath + "/" + file.Name())
if err != nil {
log.Fatal(err)
}
hclConfig[file.Name()] = fileContent
}
// Iterate all file contents
for k, v := range hclConfig {
parsedConfig, diags := hclsyntax.ParseConfig(v, k, hcl.Pos{Line: 1, Column: 1})
if diags.HasErrors() {
log.Fatal(diags)
}
diags = gohcl.DecodeBody(parsedConfig.Body, nil, c)
if diags.HasErrors() {
log.Fatal(diags)
}
}
for _, v := range c.Variables {
var variableType string
var variableDefault string
if v.Type != nil {
variableType = (v.Type.Expr).Variables()[0].RootName()
}
if v.Default != nil {
variableDefault = (v.Default.Expr).Variables()[0].RootName()
}
variables = append(variables, map[string]string{"name": v.Name, "description": v.Description,
"sensitive": strconv.FormatBool(v.Sensitive), "type": variableType, "default": variableDefault})
}
for _, v := range c.Outputs {
outputs = append(outputs, map[string]string{"name": v.Name, "description": v.Description,
"sensitive": strconv.FormatBool(v.Sensitive), "value": v.Value})
}
parsedConfig["variables"], parsedConfig["outputs"] = variables, outputs
return parsedConfig
}
问题:如何从资源块中解析多个标签?
正确答案
您分享的错误是由于 type resource
的定义造成的。 terraform 中的 resource
块(和 data
块)需要两个标签,指示资源类型和名称。为了匹配您使用这些结构类型暗示的架构,您需要定义标记为 label
的字段:
type Resource struct {
Type string `hcl:"type,label"`
Name string `hcl:"name,label"`
Options hcl.Body `hcl:",remain"`
}
type Data struct {
Type string `hcl:"type,label"`
Name string `hcl:"name,label"`
Options hcl.Body `hcl:",remain"`
}
虽然这应该适用于您在此处显示的有限输入,但我想提醒您正在使用更高级别的 gohcl
api,它只能解码 hcl 的子集,该子集很好地映射到 go 的结构类型。 terraform本身直接使用了hcl.Body
和hcl.Expression
的低级api,这使得terraform语言可以包含一些gohcl
api无法直接表示的hcl功能。
根据您的目标,您可能会发现使用官方库 terraform-config-inspect
更好,它可以在比 hcl api 本身更高的抽象级别上解析、解码和描述 terraform 语言的子集。它还支持为 terraform 版本编写的模块,一直追溯到 terraform v0.11,并且是支持 Terraform Registry 完成的模块分析的实现。
理论要掌握,实操不能落!以上关于《HCL 解码:具有多个标签的块》的详细介绍,大家都掌握了吧!如果想要继续提升自己的能力,那么就来关注编程网公众号吧!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341