首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >HCL解码:具有多个标签的块

HCL解码:具有多个标签的块
EN

Stack Overflow用户
提问于 2022-05-11 07:42:33
回答 1查看 725关注 0票数 3

我的目标是解析一个HCL配置(),然后将收集到的有关变量、输出、资源块和数据块的数据写入Markdown文件。

但是,只要我试图解码具有多个标签的资源块,变量和输出就没有问题。

Works:

代码语言:javascript
复制
variable "foo" {
  type = "bar"
}

不工作:

代码语言:javascript
复制
resource "foo" "bar" {
 name = "biz"
}

错误:Extraneous label for resource; Only 1 labels (name) are expected for resource blocks.

类型声明代码:

代码语言:javascript
复制
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"`
}

解码码:

代码语言:javascript
复制
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
}

问题:如何从资源块解析多个标签?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-05-11 23:48:29

您所共享的错误是由于type Resource的定义造成的。Terraform中的resource块(和data块)需要两个标签,指示资源类型和名称。为了在模式中与这些结构类型相匹配,您需要定义为标记为label的字段

代码语言:javascript
复制
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,它只能解码映射到Go结构类型的HCL的一个子集。Terraform本身直接使用hcl.Bodyhcl.Expression的低级API,这允许Terraform语言包含gohcl API无法直接表示的一些gohcl特性。

根据您的目标,您可能会发现使用官方库terraform-config-inspect更好,它可以在比HCL本身更高的抽象级别上解析、解码和描述Terraform语言的子集。它还支持为Terraform版本编写的模块,可以追溯到Terraformv0.11,是支持Terraform注册表对模块进行分析的实现。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72197201

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档