Terraform Schema Elem Поддержка нескольких типов? - PullRequest
1 голос
/ 15 июня 2019

Может ли схема Terraform поддерживать несколько типов схем для Elem?Проблема, которую я пытаюсь решить, состоит в том, что данные из моего внешнего API - это массив, который имеет несколько типов - некоторые элементы являются строками, а некоторые - списками.Например, значение будет выглядеть примерно так:

condition = [
    "and",
    [
        "contains",
        ["foo","bar","baz"],
        "website"
    ]

И затем я создаю схему для этого свойства, которая будет выглядеть примерно так:

"condition": {
    Type:     schema.TypeList,
    Required: true,
    Elem: &schema.Schema{
        Type: schema.TypeList,
    },
},

Но, когда я запускаю свой тест, яполучите сообщение, которое говорит:

condition.0: should be a list

Что, это имеет смысл, потому что мое определение схемы объявляет, что каждый Elem должен быть списком.Есть ли способ определить несколько типов для Elem?

ОБНОВЛЕНИЕ:

Я изменил свое поле condition из приведенного выше, чтобы оно было

"condition_json": {
  Type:     schema.TypeString,
  Required: true,
},

Мой .tf файл теперь использует jsonencode(), например, так:


variable "condition_list" {
    default = [
        ["and"],
        ["contains",["path","payload","source"],"website"],
        ["contains",["path","headers","from","0","address"],"homer"]
    ]
}
resource "event_rule" "first" {
    condition_json = "${jsonencode(var.condition_list)}"
}

Когда я создаю свою структуру для моего объекта правила события, поле Condition получает значениеиз condition_json примерно так:

Condition: d.Get("condition_json").([]interface{}),

Поскольку мое поле Condition в библиотеке, взаимодействующей с API, выглядит следующим образом:

Condition         []interface{} `json:"condition,omitempty"`

Моя проблема в том, что я получаю ошибку, которая

interface {} is string, not []interface {}

Это сообщение имеет смысл, потому что у меня есть схема, установленная на TypeString, но в моей структуре, взаимодействующей с API, я Condition напечатан как []interface{}.У меня вопрос, есть ли способ привести d.Get ("condition_json") к []interface{} вместо того, чтобы утверждать?

Я явно что-то упускаю, и я не уверен, что именно.:)

1 Ответ

1 голос
/ 17 июня 2019

В текущем (на момент написания) Terraform SDK это невозможно: каждое значение должно иметь определенный определенный тип, поскольку SDK использует его для правильного декодирования данных, хранящихся в снимках состояния Terraform.

Обычный обходной путь для этого ограничения в провайдерах сегодня состоит в том, чтобы иметь поле строкового типа, которое принимает сериализацию значения JSON. Чтобы в будущем разрешить миграцию от этого обходного пути, эти атрибуты условно именуются суффиксом _json, например, condition_json в вашем случае. Terraform 0.12 улучшил надежность функции jsonencode, чтобы упростить предоставление значений для таких атрибутов без необходимости писать строки JSON вручную в конфигурации.

В Terraform 0.12 появилась поддержка динамически типизированных атрибутов на уровне ядра и в протоколе провайдера, поэтому в будущей версии Terraform SDK будет предусмотрена возможность определять атрибут как тип во время выполнения. То есть тип значения будет включен в сообщение, отправленное по проводам, а не предполагается из схемы. В этот момент вы можете использовать этот режим для своего атрибута здесь. Если вы ранее использовали обходной путь атрибута _json в этот момент, было бы возможно одновременно поддерживать режим JSON и режим динамического типа для постепенного перехода.

...