无法将 terraform variables.tf 文件读入 may go program

如何解决无法将 terraform variables.tf 文件读入 may go program

我正在尝试编写一个 go 程序,该程序读取 terraform variables.tf 并填充一个结构以供以后操作。但是,在尝试“解析”文件时出现错误。我希望有人能告诉我我做错了什么:

代码:

package main

import (
    "fmt"
    "io/ioutil"
    "log"
    "os"

    "github.com/hashicorp/hcl/v2"
    "github.com/hashicorp/hcl/v2/gohcl"
    "github.com/hashicorp/hcl/v2/hclsyntax"
)

type Config struct {
    Upstreams []*TfVariable `hcl:"variable,block"`
}

type TfVariable struct {
    Name string `hcl:",label"`
    // Default     string `hcl:"default,optional"`
    Type        string `hcl:"type"`
    Description string `hcl:"description,attr"`
    // validation block
    Sensitive bool `hcl:"sensitive,optional"`
}

func main() {
    readHCLFile("examples/string.tf")
}

// Exits program by sending error message to standard error and specified error code.
func abort(errorMessage string,exitcode int) {
    fmt.Fprintln(os.Stderr,errorMessage)
    os.Exit(exitcode)
}

func readHCLFile(filePath string) {
    content,err := ioutil.ReadFile(filePath)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("File contents: %s",content) // TODO: Remove me

    file,diags := hclsyntax.ParseConfig(content,filePath,hcl.Pos{Line: 1,Column: 1})
    if diags.HasErrors() {
        log.Fatal(fmt.Errorf("ParseConfig: %w",diags))
    }

    c := &Config{}
    diags = gohcl.DecodeBody(file.Body,nil,c)
    if diags.HasErrors() {
        log.Fatal(fmt.Errorf("DecodeBody: %w",diags))
    }

    fmt.Println(c) // TODO: Remove me
}

错误

File contents: variable "image_id" {
  type        = string
  description = "The id of the machine image (AMI) to use for the server."
  sensitive   = false
}

variable "other_id" {
  type        = string
  description = "The id of the machine image (AMI) to use for the server."
  sensitive   = true
}
2021/03/13 19:55:49 DecodeBody: examples/string.tf:2,17-23: Variables not allowed; Variables may not be used here.,and 3 other diagnostic(s)
exit status 1

堆栈驱动程序 question 可悲地用于 hcl1

Blog post 我正在引用。

解决方法

它看起来像是库的错误/功能,因为一旦您将 string 更改为 "string",例如,

variable "image_id" {
  type        = string
  ...

variable "image_id" {
  type        = "string"
  ...

gohcl.DecodeBody 成功。

--- 更新---

所以,他们确实在 Terraform 中使用了这个包,但是他们 custom-parse configs,即他们不使用 gohcl.DecodeBody。它们还通过使用 typecustom-treathcl.ExprAsKeyword)来 compare description 属性。正如您所假设的,它们确实对 type 使用了 custom type,但您不必使用自定义解析。

下面是一个工作示例:

package main

import (
    "fmt"
    "log"
    "os"

    "github.com/hashicorp/hcl/v2"
    "github.com/hashicorp/hcl/v2/gohcl"
    "github.com/hashicorp/hcl/v2/hclsyntax"
)

var (
    configFileSchema = &hcl.BodySchema{
        Blocks: []hcl.BlockHeaderSchema{
            {
                Type:       "variable",LabelNames: []string{"name"},},}

    variableBlockSchema = &hcl.BodySchema{
        Attributes: []hcl.AttributeSchema{
            {
                Name: "description",{
                Name: "type",{
                Name: "sensitive",}
)

type Config struct {
    Variables []*Variable
}

type Variable struct {
    Name        string
    Description string
    Type        string
    Sensitive   bool
}

func main() {
    config := configFromFile("examples/string.tf")
    for _,v := range config.Variables {
        fmt.Printf("%+v\n",v)
    }
}

func configFromFile(filePath string) *Config {
    content,err := os.ReadFile(filePath) // go 1.16
    if err != nil {
        log.Fatal(err)
    }

    file,diags := hclsyntax.ParseConfig(content,filePath,hcl.Pos{Line: 1,Column: 1})
    if diags.HasErrors() {
        log.Fatal("ParseConfig",diags)
    }

    bodyCont,diags := file.Body.Content(configFileSchema)
    if diags.HasErrors() {
        log.Fatal("file content",diags)
    }

    res := &Config{}

    for _,block := range bodyCont.Blocks {
        v := &Variable{
            Name: block.Labels[0],}

        blockCont,diags := block.Body.Content(variableBlockSchema)
        if diags.HasErrors() {
            log.Fatal("block content",diags)
        }

        if attr,exists := blockCont.Attributes["description"]; exists {
            diags := gohcl.DecodeExpression(attr.Expr,nil,&v.Description)
            if diags.HasErrors() {
                log.Fatal("description attr",diags)
            }
        }

        if attr,exists := blockCont.Attributes["sensitive"]; exists {
            diags := gohcl.DecodeExpression(attr.Expr,&v.Sensitive)
            if diags.HasErrors() {
                log.Fatal("sensitive attr",exists := blockCont.Attributes["type"]; exists {
            v.Type = hcl.ExprAsKeyword(attr.Expr)
            if v.Type == "" {
                log.Fatal("type attr","invalid value")
            }
        }

        res.Variables = append(res.Variables,v)
    }
    return res
}

为完整性添加,example/string.tf

variable "image_id" {
  type        = string
  description = "The id of the machine image (AMI) to use for the server."
  sensitive   = false
}

variable "other_id" {
  type        = string
  description = "The id of the machine image (AMI) to use for the server."
  sensitive   = true
}
,

由于 Terraform 语言广泛使用了需要使用低级 HCL API 进行自定义编程的各种 HCL 功能,因此 Terraform 团队维护了一个 Go 库 terraform-config-inspect,它对 Terraform 语言的理解足以提取有关 top 的静态元数据级对象,包括变量。它还处理这样一个事实,即 Terraform 允许在与其他声明交错的任何 .tf.tf.json 文件中定义变量;将它们放在 variables.tf 中只是一种约定。

例如:

mod,diags := tfconfig.LoadModule("examples")
if diags.HasErrors() {
    log.Fatalf(diags.Error())
}
for _,variable := range mod.Variables {
    fmt.Printf("%#v\n",variable)
}

此库与 Terraform Registry 用于生成 the documentation about module input variables 的代码相同,因此它支持 Terraform Registry 所做的所有 Terraform 语言版本(在撰写本文时,可以追溯到 Terraform v0.1)。 10 语言,因为这是第一个可以从注册表安装模块的版本)并支持 Terraform 语言的 HCL 原生语法和 JSON 表示。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams['font.sans-serif'] = ['SimHei'] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -> systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping("/hires") public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate<String
使用vite构建项目报错 C:\Users\ychen\work>npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)> insert overwrite table dwd_trade_cart_add_inc > select data.id, > data.user_id, > data.course_id, > date_format(
错误1 hive (edu)> insert into huanhuan values(1,'haoge'); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive> show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 <configuration> <property> <name>yarn.nodemanager.res