我的编程空间,编程开发者的网络收藏夹
学习永远不晚

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

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

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.Bodyhcl.Expression的低级api,这使得terraform语言可以包含一些gohcl api无法直接表示的hcl功能。

根据您的目标,您可能会发现使用官方库 terraform-config-inspect 更好,它可以在比 hcl api 本身更高的抽象级别上解析、解码和描述 terraform 语言的子集。它还支持为 terraform 版本编写的模块,一直追溯到 terraform v0.11,并且是支持 Terraform Registry 完成的模块分析的实现。

理论要掌握,实操不能落!以上关于《HCL 解码:具有多个标签的块》的详细介绍,大家都掌握了吧!如果想要继续提升自己的能力,那么就来关注编程网公众号吧!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

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

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

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

学习知识要善于思考,思考,再思考!今天编程网小编就给大家带来《HCL 解码:具有多个标签的块》,以下内容主要包含等知识点,如果你正在学习或准备学习Golang,就都不要错过本文啦~让我们一起来看看吧,能帮助到你就更好了!问题内容我的目标是解
HCL 解码:具有多个标签的块
2024-04-04

Golang多个字段具有相同的json标签名称

欢迎各位小伙伴来到编程网,相聚于此都是缘哈哈哈!今天我给大家带来《Golang多个字段具有相同的json标签名称》,这篇文章主要讲到等等知识,如果你对Golang相关的知识非常感兴趣或者正在自学,都可以关注我,我会持续更新相关文章!当然,有
Golang多个字段具有相同的json标签名称
2024-04-04

具有多个路径的 Go 模块

php小编子墨介绍:最近,Go语言中的模块管理工具又迎来了新的功能——多路径模块。这一功能的引入,使得开发者在使用Go模块时可以更加灵活地指定模块的路径。以往,开发者只能将模块安装在固定的路径下,导致模块的依赖关系较为复杂。而现在,多路径模
具有多个路径的 Go 模块
2024-02-10

dedecms织梦TAG标签显示单个标签共有多少篇文章的方法

我们在进行织梦dedecms模板设计的时候,想实现tag的链接和tag名的同时,还能显示每个tag关联的文章的数量。 但是织梦默认没有这http://www.cppcns.com样的标签来调用,这就需要我们自己对系统文件进行修改来实现了,具
2022-06-12

同时调用具有不同签名的多个函数

学习知识要善于思考,思考,再思考!今天编程网小编就给大家带来《同时调用具有不同签名的多个函数》,以下内容主要包含等知识点,如果你正在学习或准备学习Golang,就都不要错过本文啦~让我们一起来看看吧,能帮助到你就更好了!问题内容我想要一些关
同时调用具有不同签名的多个函数
2024-04-05

将具有多个程序的 GOPATH 存储库转换为 GO 模块

Golang小白一枚,正在不断学习积累知识,现将学习到的知识记录一下,也是将我的所得分享给大家!而今天这篇文章《将具有多个程序的 GOPATH 存储库转换为 GO 模块》带大家来了解一下##content_title##,希望对大家的知识积
将具有多个程序的 GOPATH 存储库转换为 GO 模块
2024-04-04

如何编写具有不同签名的同一方法的多个实现

从现在开始,我们要努力学习啦!今天我给大家带来《如何编写具有不同签名的同一方法的多个实现》,感兴趣的朋友请继续看下去吧!下文中的内容我们主要会涉及到等等知识点,如果在阅读本文过程中有遇到不清楚的地方,欢迎留言呀!我们一起讨论,一起学习!问题
如何编写具有不同签名的同一方法的多个实现
2024-04-04

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录