Я пишу собственный провайдер с 2-х уровневой глубоко вложенной картой.Я могу расширить схему при вызове функции создания.Однако у меня возникают проблемы, когда я пытаюсь установить это значение из функции чтения после создания этого ресурса.Я пытался выполнить шаги документации Terraform, раздел «Сложное чтение», но получаю ошибку Invalid address to set: []string{"docker_info", "0", "port_mapping"}
.
Схема выглядит следующим образом:
"docker_info": {
Type: schema.TypeList,
Required: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"image": &schema.Schema{
Type: schema.TypeString,
Required: true,
},
"force_pull_image": &schema.Schema{
Type: schema.TypeBool,
Optional: true,
Default: "false",
},
"network": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Default: "BRIDGE",
ValidateFunc: validateDockerNetwork,
},
// We use typeSet because this parameter can be unordered list and must be unique.
"port_mapping": &schema.Schema{
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"host_port": &schema.Schema{
Type: schema.TypeInt,
Required: true,
},
"container_port": &schema.Schema{
Type: schema.TypeInt,
Required: true,
},
"container_port_type": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ValidateFunc: validateSingularityPortMappingType,
},
"host_port_type": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ValidateFunc: validateSingularityPortMappingType,
},
"protocol": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ValidateFunc: validateSingularityPortProtocol,
Default: "tcp",
},
},
},
},
},
},
},
в моей функции чтения, у меня есть:
d.Set("docker_info", flattenDockerInfo(ContainerInfo.DockerInfo))
func flattenDockerInfo(in singularity.DockerInfo) []interface{} {
var out = make([]interface{}, 0, 0)
m := make(map[string]interface{})
m["network"] = in.Network
m["image"] = in.Image
m["force_pull_image"] = in.ForcePullImage
if len(in.PortMappings) > 0 {
m["port_mapping"] = flattenDockerPortMappings(in.PortMappings)
}
out = append(out, m)
return out
}
func flattenDockerPortMappings(in []singularity.DockerPortMapping []map[string]interface{} {
var out = make([]map[string]interface{}, len(in), len(in))
for i := range in {
m := make(map[string]interface{})
m["container_port"] = v.ContainerPort
m["container_port_type"] = v.ContainerPortType
m["host_port"] = v.HostPort
m["host_port_type"] = v.HostPortType
m["protocol"] = v.Protocol
out[i] = m
}
return out
}
singularityDocker struct:
type DockerInfo struct {
Parameters map[string]string
`json:"parameters,omitempty"`
ForcePullImage bool
`json:"forcePullImage,omitempty"`
SingularityDockerParameters []SingularityDockerParameter
`json:"dockerParameters,omitEmpty"`
Privileged bool
`json:"privileged,omitEmpty"`
Network string
`json:"network,omitEmpty"` //Value can be BRIDGE, HOST, or NONE
Image string
`json:"image"`
PortMappings []DockerPortMapping
`json:"portMappings,omitempty"`
}
type DockerPortMapping struct {
ContainerPort int64 `json:"containerPort"`
ContainerPortType string `json:"containerPortType,omitempty"`
HostPort int64 `json:"hostPort"`
HostPortType string `json:"hostPortType,omitempty"`
Protocol string `json:"protocol,omitempty"`
}
Iожидаю увидеть что-то вроде
"docker_info.0.port_mapping.3218452487.container_port": "8888",
"docker_info.0.port_mapping.3218452487.container_port_type": "LITERAL",
"docker_info.0.port_mapping.3218452487.host_port": "0",
"docker_info.0.port_mapping.3218452487.host_port_type": "FROM_OFFER",
"docker_info.0.port_mapping.3218452487.protocol": "tcp",
Я обнаружил, что, добавив приведенный ниже код для создания typeSet
m["port_mapping"] = schema.NewSet(portMappingHash, []interface{}{flattenDockerPortMappings(in.PortMappings)})
func portMappingHash(v interface{}) int {
var buf bytes.Buffer
x := v.([]map[string]interface{})
for i := range x {
buf.WriteString(fmt.Sprintf("%s-%d", "test", i))
}
return hashcode.String(buf.String())
}
, теперь я получаю docker_info.0.port_mapping.2384314926: '' expected a map, got 'slice'