我正在使用 Terraform 插件框架为 Ansible Forms 编写一个自定义 Terraform 提供程序(GitHub - hashicorp/terraform-plugin-framework:用于构建 Terraform 提供程序的下一代框架。v1.8.0)。如何读取类型为 types.Dynamic 的字段中的 JSON 字符串? JSON 字符串本身包含一个值类型不同的映射。
这是我的 DS 模型:
type JobDataSourceModel struct {
CxProfileName types.String `tfsdk:"cx_profile_name"`
...
Extravars types.Dynamic `tfsdk:"extravars"`
...
}
这是
Schema()
方法:
func (d *JobDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
Attributes: map[string]schema.Attribute{
...
"extravars": schema.DynamicAttribute{
MarkdownDescription: "",
Computed: true,
},
...
},
}
}
Read()
方法:
func (d *JobDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var data JobDataSourceModel
...
data.Extravars = types.DynamicValue(restInfo.Data.Extravars)
...
}
Ansible Forms API 返回的数据如下。
extravars
字段是 API 响应中的 JSON 字符串。我正在将 extravars
的值转换为地图。映射值具有 diff 类型,例如列表、字符串和布尔值。这就是为什么我想使用types.Dynamic
。
{
"status": "success",
"message": "job ran successfully",
"data": {
"id": 86,
"form": "Demo Form Ansible No input",
"target": "Demo Form Ansible No input",
"status": "success",
"start": "2024-05-02T15:35:16.000Z",
"end": "2024-05-02T15:35:18.000Z",
"user": "admin",
"user_type": "local",
"job_type": "ansible",
"extravars": "{\"name\":\"vm1\",\"region\":\"myregion\",\"opco\":\"myopco\",\"svm_name\":\"mysvm_name\",\"exposure\":\"myexposure\",\"env\":\"myenv\",\"dataclass\":\"mydataclass\",\"share_name\":\"myshare_name\",\"accountid\":\"myaccountid\",\"size\":\"mysize\",\"protection_required\":\"myprotection_required\",\"ansibleforms_user\":{\"username\":\"admin\",\"id\":1,\"type\":\"local\",\"groups\":[\"local/admins\"],\"roles\":[\"public\",\"admin\"]},\"__playbook__\":\"dummy.yaml\",\"__inventory__\":\"\",\"__credentials__\":{\"vcenterCredentials\":\"VCENTER\"}}",
"credentials": "{\"vcenterCredentials\":\"VCENTER\"}",
"notifications": "{}",
"approval": null,
"step": null,
"parent_id": null,
"subjobs": null,
"no_of_records": 45,
"counter": 8,
"output": "<span class='has-text-warning'>[WARNING]: No inventory was parsed, only implicit localhost is available</span> <span class='tag is-info is-light'>2024-05-02 15:35:17</span>\r\n<span class='has-text-warning'>[WARNING]: provided hosts list is empty, only localhost is available. Note that</span> <span class='tag is-info is-light'>2024-05-02 15:35:17</span>\r\n<span class='has-text-warning'>the implicit localhost does not match 'all'</span>\r\n<span class='has-text-warning'>[WARNING]: Found variable using reserved name: name</span> <span class='tag is-info is-light'>2024-05-02 15:35:17</span>\r\n\n<span class='has-text-weight-bold'>PLAY [This is a hello-world example] *******************************************</span> <span class='tag is-info is-light'>2024-05-02 15:35:17</span>\r\n\r\n<span class='has-text-weight-bold'>TASK [Gathering Facts] *********************************************************</span>\r\n<span class='has-text-success'>ok: [localhost]</span> <span class='tag is-info is-light'>2024-05-02 15:35:18</span>\r\n\r\n<span class='has-text-weight-bold'>TASK [Output 'Welcome'.] *******************************************************</span>\r\n<span class='has-text-success'>ok: [localhost] => </span> <span class='tag is-info is-light'>2024-05-02 15:35:18</span>\r\n<span class='has-text-success'> msg: Hi there and welcome to ansible</span>\r\n\r\n<span class='has-text-weight-bold'>PLAY RECAP *********************************************************************</span>\r\n<span class=''>localhost : <span class='tag is-success'>ok=2</span> changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0</span>\r\n<span class='has-text-success'>ok: [Playbook finished] with status (0)</span> <span class='tag is-info is-light'>2024-05-02 15:35:18</span>"
}
}
我尝试使用上面的代码执行此操作,但它不起作用。
寻找具有类似 json 输入的 terraform 资源示例,发现这是一个:
resource "aws_api_gateway_stage" "deploy" {
depends_on = [
aws_api_gateway_account.demo
]
deployment_id = aws_api_gateway_deployment.deploy.id
rest_api_id = aws_api_gateway_rest_api.x.id
stage_name = "test"
access_log_settings {
destination_arn = aws_cloudwatch_log_group.logs.arn
format = "{ \"requestId\":\"$context.requestId\" }"
}
}
查看 json 数据的格式及其代码:
Schema: map[string]*schema.Schema{
"access_log_settings": {
Type: schema.TypeList,
MaxItems: 1,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"destination_arn": {
Type: schema.TypeString,
Required: true,
ValidateFunc: verify.ValidARN,
},
"format": {
Type: schema.TypeString,
Required: true,
},
},
},
},
...
...如果您需要从该 json 字符串中读取某些内容,请使用
json.Unmarshal
有很多示例,这里是一个:
https://go.dev/play/p/zdMq5_ex8G