Написание провайдера Terraform с вложенной картой - PullRequest
0 голосов
/ 04 января 2019

Я пишу собственный провайдер с 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'

...